{"id":1393,"date":"2020-07-30T07:41:44","date_gmt":"2020-07-29T22:41:44","guid":{"rendered":"http:\/\/168.138.214.208\/?p=1393"},"modified":"2020-08-28T19:25:40","modified_gmt":"2020-08-28T10:25:40","slug":"post-1393","status":"publish","type":"post","link":"https:\/\/nobunobu1717.site\/?p=1393","title":{"rendered":"[Rails6] CarrierWave\u3067Active Record(Active Storage)\u3092\u4f7f\u7528\u305b\u305a\u306bGCS\u306b\u753b\u50cf\u3092\u30a2\u30c3\u30d7\u3059\u308b\u65b9\u6cd5"},"content":{"rendered":"<div id=\"toc_container\" class=\"no_bullets\"><p class=\"toc_title\">Contents<\/p><ul class=\"toc_list\"><li><a href=\"#i\"><span class=\"toc_number toc_depth_1\">1<\/span> \u80cc\u666f<\/a><\/li><li><a href=\"#i-2\"><span class=\"toc_number toc_depth_1\">2<\/span> \u65b9\u6cd5<\/a><\/li><li><a href=\"#i-3\"><span class=\"toc_number toc_depth_1\">3<\/span> \u307e\u3068\u3081<\/a><\/li><\/ul><\/div>\n<h2><span id=\"i\">\u80cc\u666f<\/span><\/h2>\n<p>\u73fe\u5728Ruby on Rails6\u3067\u4f5c\u6210\u3057\u305f\u30a2\u30d7\u30ea\u3092Heroku\u306e\u7121\u6599\u30d7\u30e9\u30f3\u3067\u904b\u7528\u3057\u3066\u304a\u308a\u3001<\/p>\n<p>1. \u753b\u50cf\u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306fActive Storage\u3092\u4f7f\u7528\u3057\u3066GCS(Google Cloud Storage)\u306b\u884c\u3063\u3066\u3044\u308b\u3002<br \/>\n2. DB\u306fPostgres\u3092\u4f7f\u7528\u3057\u3066\u3044\u308b\u304c\u3001\u7121\u6599\u30d7\u30e9\u30f3\u3067\u4f7f\u7528\u3067\u304d\u308b\u306e\u306f10,000\u30ec\u30b3\u30fc\u30c9\u307e\u3067\u3002<br \/>\n3. Active Storage\u3068Active Record\u3092\u4f7f\u7528\u3059\u308b\u3068\u3001\u88cf\u3067DB\u306b\u30c6\u30fc\u30d6\u30eb\u3068\u30ec\u30b3\u30fc\u30c9\u304c\u4f5c\u3089\u308c\u308b\u3002<br \/>\n4. \u753b\u50cf\u3092\u591a\u304f\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3059\u308b\u3068\u3001\u30c6\u30fc\u30d6\u30eb\u306e\u30ec\u30b3\u30fc\u30c9\u304c\u5927\u91cf\u306b\u6d88\u8cbb\u3055\u308c\u3066\u3057\u307e\u3044\u3001\u30ec\u30b3\u30fc\u30c9\u6570\u306e\u4e0a\u9650\u306b\u9054\u3057\u3066\u3057\u307e\u3046\u3002<\/p>\n<p>\u901a\u5e38\u306e\u4f7f\u7528\u4f8b(1\u3064\u306eActive Record\u306bavatar\u306a\u3069\u3067\u753b\u50cf\u3092\u4fdd\u5b58\u3059\u308b\u5f62)\u3067\u3042\u308c\u3070\u3001\u305d\u3093\u306a\u306b\u554f\u984c\u306a\u3089\u7121\u3044\u304b\u3082\u3057\u308c\u306a\u3044\u304c\u3001<br \/>\n\u4eca\u56de\u306fajax\u3067\u753b\u50cf\u30921\u30641\u3064\u4fdd\u5b58\u3057\u3001\u4f55\u4ef6\u3082\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3092\u884c\u3046\u305f\u3081\u3001\u5927\u91cf\u306b\u6d88\u8cbb\u3057\u3066\u3057\u307e\u3046\u305f\u3081\u306b\u554f\u984c\u3068\u306a\u308b\u3002<\/p>\n<p>\u306a\u306e\u3067\u3001\u7121\u6599\u67a0\u3067\u4f7f\u7528\u53ef\u80fd\u306a\u3088\u3046\u306b\u6975\u529b\u30c6\u30fc\u30d6\u30eb\u306e\u30ec\u30b3\u30fc\u30c9\u6570\u3092\u6e1b\u3089\u3059\u305f\u3081\u306b\u3001\u753b\u50cf\u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u6a5f\u80fd\u3092Active Storage\u3068Active Record\u3092\u4f7f\u7528\u3057\u306a\u3044\u65b9\u6cd5\u306b\u5909\u66f4\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002<\/p>\n<h2><span id=\"i-2\">\u65b9\u6cd5<\/span><\/h2>\n<p>CarrierWave\u3068\u3044\u3046gem\u3092\u4f7f\u7528\u3059\u308b\u3002<br \/>\n\u3053\u308c\u306fActive Storage\u304c\u767b\u5834\u3059\u308b\u524d\u304b\u3089\u5b58\u5728\u3057\u3066\u3044\u3066\u3001\u591a\u304f\u306e\u753b\u50cf\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u51e6\u7406\u3067\u4f7f\u7528\u3055\u308c\u3066\u3044\u308b\u30c7\u30d5\u30a1\u30af\u30c8\u30b9\u30bf\u30f3\u30c0\u30fc\u30c9\u307f\u305f\u3044\u306a\u30e9\u30a4\u30d6\u30e9\u30ea\u3067\u3042\u308b\u3002<br \/>\n\u3082\u3061\u308d\u3093S3\u3084GCS\u306a\u3069\u306e\u30af\u30e9\u30a6\u30c9\u30b9\u30c8\u30ec\u30fc\u30b8\u306b\u3082\u5bfe\u5fdc\u3057\u3066\u3044\u308b\u3002<\/p>\n<h3>GEM<\/h3>\n<p>\u4e0b\u8a18\u306egem\u3092gemfile\u306b\u8a18\u8f09\u3057\u3066\u3001bundle install\u3067\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3059\u308b\u3002<br \/>\n\u753b\u50cf\u306e\u5727\u7e2e\u306a\u3069\u306e\u52a0\u5de5\u3092\u3057\u306a\u3044\u306a\u3089\u3070mini_magick\u306f\u4e0d\u8981\u3002<\/p>\n<pre class=\"lang:default decode:true \"># for gcs\ngem 'carrierwave'\ngem 'fog-google'\ngem 'mini_magick'\n<\/pre>\n<h3>\u5b9f\u88c5<\/h3>\n<h4>Uploader<\/h4>\n<p>CarrierWave\u306e\u304a\u4f5c\u6cd5\u306b\u6cbf\u3063\u3066\u3001Uploader\u30af\u30e9\u30b9\u3092\u5b9f\u88c5\u3059\u308b\u3002<\/p>\n<p>1. mini_magic\u306b\u3088\u308b\u753b\u50cf\u306e\u30ea\u30b5\u30a4\u30ba<br \/>\n2. \u672c\u756a\u74b0\u5883\u4ee5\u5916\u306f\u30ed\u30fc\u30ab\u30eb\u306b\u753b\u50cf\u3092\u4fdd\u5b58\u3059\u308b<\/p>\n<p>\u3088\u3046\u306b\u3057\u3066\u3044\u308b\u3002<\/p>\n<pre class=\"lang:default decode:true \">class ImageUploader &lt; CarrierWave::Uploader::Base\n  include CarrierWave::MiniMagick\n\n  process resize_to_fit: [700, 700]\n\n  # test env upload loacal\n  if Rails.env.development?\n    storage :file\n  elsif Rails.env.test?\n    storage :file\n  else\n    storage :fog\n  end\nend<\/pre>\n<h4>ActiveModel\u306b\u3088\u308b\u5b9f\u88c5<\/h4>\n<p>CarrierWave\u306e\u3088\u304f\u3042\u308b\u30b5\u30f3\u30d7\u30eb\u3060\u3068\u3001\u4e0a\u8a18\u306eUploader\u3092Active Record\u306e\u30e1\u30f3\u30d0\u30fc\u306b\u5b9f\u88c5\u3059\u308b\u3002<br \/>\n\u3053\u306e\u5834\u5408\u3060\u3068\u3001DB\u306b\u30ec\u30b3\u30fc\u30c9\u304c\u4fdd\u5b58\u3055\u308c\u3066\u3057\u307e\u3046\u305f\u3081\u3001\u4eca\u56de\u306e\u76ee\u7684\u306b\u5408\u81f4\u3057\u306a\u3044\u3002<br \/>\n\u8abf\u3079\u305f\u3068\u3053\u308d\u3001Active Record\u3067\u306f\u7121\u304fActive Model\u306b\u5b9f\u88c5\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3053\u3068\u304c\u308f\u304b\u3063\u305f\u3002<\/p>\n<p><a href=\"http:\/\/thoames.hatenadiary.jp\/entry\/2018\/02\/14\/025122\" target=\"_blank\" rel=\"noopener noreferrer\">\u53c2\u8003<\/a><\/p>\n<p>\u4e0b\u8a18\u306e\u3088\u3046\u306b\u3001store\u30e1\u30bd\u30c3\u30c9\u3092\u547c\u3073\u51fa\u3059\u3053\u3068\u3067\u753b\u50cf\u304c\u4fdd\u5b58\u53ef\u80fd\u306b\u306a\u308b\u3002<\/p>\n<pre class=\"lang:default decode:true \">class ImageAttachment\n  include ActiveModel::Model\n  extend CarrierWave::Mount\n\n  attr_accessor :image\n  mount_uploader :image, ImageUploader\n\n  def save(image)\n    self.image.store!(image)\n  end\nend<\/pre>\n<h4>CGS\u8a2d\u5b9a<\/h4>\n<p>GCS\u306e\u30d0\u30b1\u30c3\u30c8\u306e\u8a2d\u5b9a\u3092\u884c\u3046\u305f\u3081\u306b\u3001config\/initializers\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u4ee5\u4e0b\u306bcarrierwave.rb\u3092\u4f5c\u6210\u3057\u3066\u8a2d\u5b9a\u3092\u884c\u3046\u3002<br \/>\nActive Storage\u3067\u4f7f\u7528\u3057\u3066\u3044\u305f\u74b0\u5883\u5909\u6570\u304c\u305d\u306e\u307e\u307e\u4f7f\u7528\u3067\u304d\u3066\u4fbf\u5229\u3067\u3042\u3063\u305f\u3002<\/p>\n<pre class=\"lang:default decode:true \">CarrierWave.configure do |config|\n  config.fog_provider = 'fog\/google'\n  config.fog_credentials = {\n    provider: 'Google',\n    google_project: ENV['GCS_PROJECT'],\n    google_json_key_string: ENV['GOOGLE_CREDENTIALS'].as_json\n  }\n  config.fog_directory = ENV['GCS_BUCKET']\nend\nCarrierWave::SanitizedFile.sanitize_regexp = \/[^[:word:]\\.\\-\\+]\/<\/pre>\n<h4>CGS\u306e\u30d0\u30b1\u30c3\u30c8\u8a2d\u5b9a<\/h4>\n<p>\u30c7\u30d5\u30a9\u30eb\u30c8\u306e\u753b\u50cf\u4fdd\u5b58\u5148\u306f\u3001uploads\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u306a\u308b\u305f\u3081\u3001<br \/>\n\u305d\u306e\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u516c\u958b\u8a2d\u5b9a\u3092\u884c\u3046\u5fc5\u8981\u304c\u3042\u308b\u3002<br \/>\n\u516c\u958b\u8a2d\u5b9a\u306b\u95a2\u3057\u3066\u306f\u4e0b\u8a18\u306e\u30aa\u30d5\u30a3\u30b7\u30e3\u30eb\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u306e\u901a\u308a\u306b\u5b9f\u65bd\u3059\u308c\u3070\u826f\u3044\u3002<br \/>\nhttps:\/\/cloud.google.com\/storage\/docs\/access-control\/making-data-public?hl=ja<\/p>\n<p>\u3061\u306a\u307f\u306b\u3001Uploader\u306estore_dir\u30e1\u30bd\u30c3\u30c9\u3092\u30aa\u30fc\u30d0\u30fc\u30e9\u30a4\u30c9\u3059\u308b\u3053\u3068\u3067\u4fdd\u5b58\u5148\u7b49\u306f\u5909\u3048\u3089\u308c\u308b\u6a21\u69d8\u3002<\/p>\n<h4>\u5b9f\u88c5<\/h4>\n<p>\u5f8c\u306fController\u3067\u3053\u308c\u3089\u3092\u547c\u3073\u51fa\u3059\u3060\u3051\u3002<br \/>\n\u4eca\u56de\u306f\u3001ajax\u3067\u753b\u50cf\u306e\u4fdd\u5b58\u3060\u3051\u3092\u884c\u3046API\u3068\u3057\u3066\u5b9f\u88c5\u3092\u884c\u306a\u3063\u3066\u3044\u305f\u306e\u3067\u4e0b\u8a18\u306e\u3088\u3046\u306b\u5b9f\u88c5\u3057\u305f\u3002<\/p>\n<pre class=\"lang:default decode:true \">  # POST adamin\/article_edit\/attach\n  def attach\n    attachment = ImageAttachment.new\n    attachment.save(ajax_params)\n    render json: { filename: attachment.image.url }\n  end\n<\/pre>\n<h2><span id=\"i-3\">\u307e\u3068\u3081<\/span><\/h2>\n<p>\u4ee5\u4e0a\u3067\u3001Active Storage\u3068Active Record\u3092\u4f7f\u7528\u305b\u305a\u306bCarrierWave\u3078\u306e\u51e6\u7406\u306e\u7f6e\u304d\u63db\u3048\u304c\u3067\u304d\u305f\u3002<br \/>\n\u4e0d\u8981\u306a\u30c6\u30fc\u30d6\u30eb\u30ec\u30b3\u30fc\u30c9\u6570\u3092\u6d88\u8cbb\u305b\u305a\u306b\u6e08\u3093\u3067\u6e80\u8db3\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Contents1 \u80cc\u666f2 \u65b9\u6cd53 \u307e\u3068\u3081 \u80cc\u666f \u73fe\u5728Ruby on Rails6\u3067\u4f5c\u6210\u3057\u305f\u30a2\u30d7\u30ea\u3092Heroku\u306e\u7121\u6599\u30d7\u30e9\u30f3\u3067\u904b\u7528\u3057\u3066\u304a\u308a\u3001 1. \u753b\u50cf\u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306fActive Storage\u3092\u4f7f &#8230; <\/p>\n","protected":false},"author":1,"featured_media":1278,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[32],"tags":[],"_links":{"self":[{"href":"https:\/\/nobunobu1717.site\/index.php?rest_route=\/wp\/v2\/posts\/1393"}],"collection":[{"href":"https:\/\/nobunobu1717.site\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nobunobu1717.site\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nobunobu1717.site\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nobunobu1717.site\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1393"}],"version-history":[{"count":5,"href":"https:\/\/nobunobu1717.site\/index.php?rest_route=\/wp\/v2\/posts\/1393\/revisions"}],"predecessor-version":[{"id":1403,"href":"https:\/\/nobunobu1717.site\/index.php?rest_route=\/wp\/v2\/posts\/1393\/revisions\/1403"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nobunobu1717.site\/index.php?rest_route=\/wp\/v2\/media\/1278"}],"wp:attachment":[{"href":"https:\/\/nobunobu1717.site\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1393"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nobunobu1717.site\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1393"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nobunobu1717.site\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1393"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}