현재 Rails 환경을 기반으로 종이 클립의 저장 메커니즘을 어떻게 설정할 수 있습니까?
S3에 모두 업로드되는 클립 첨부 파일이있는 여러 모델이있는 Rails 애플리케이션이 있습니다. 이 앱에는 매우 자주 실행되는 대규모 테스트 도구 모음도 있습니다. 단점은 테스트를 실행할 때마다 S3 계정에 수많은 파일이 업로드되어 테스트 스위트가 느리게 실행된다는 것입니다. 또한 개발 속도가 약간 느려지고 코드 작업을 위해 인터넷 연결이 필요합니다.
Rails 환경을 기반으로 종이 클립 저장 메커니즘을 설정하는 합리적인 방법이 있습니까? 이상적으로는 테스트 및 개발 환경은 로컬 파일 시스템 스토리지를 사용하고 프로덕션 환경은 S3 스토리지를 사용합니다.
또한이 동작이 필요한 여러 모델이 있으므로이 논리를 일종의 공유 모듈로 추출하고 싶습니다. 모든 모델 내부에서 이와 같은 솔루션을 피하고 싶습니다.
### We don't want to do this in our models...
if Rails.env.production?
has_attached_file :image, :styles => {...},
:path => "images/:uuid_partition/:uuid/:style.:extension",
:storage => :s3,
:url => ':s3_authenticated_url', # generates an expiring url
:s3_credentials => File.join(Rails.root, 'config', 's3.yml'),
:s3_permissions => 'private',
:s3_protocol => 'https'
else
has_attached_file :image, :styles => {...},
:storage => :filesystem
# Default :path and :url should be used for dev/test envs.
end
업데이트 : 고정 부분은 사용중인 스토리지 시스템에 따라 첨부 파일 :path
과 :url
옵션 이 달라야한다는 것 입니다.
어떤 조언이나 제안이라도 대단히 감사하겠습니다! :-)
나는 Barry의 제안을 더 좋아하고 변수를 해시로 설정하는 것을 막을 수있는 것은 없습니다. 그런 다음 종이 클립 옵션과 병합 할 수 있습니다.
config / environments / development.rb 및 test.rb에서 다음과 같이 설정하십시오.
PAPERCLIP_STORAGE_OPTIONS = {}
그리고 config / environments / production.rb
PAPERCLIP_STORAGE_OPTIONS = {:storage => :s3,
:s3_credentials => "#{Rails.root}/config/s3.yml",
:path => "/:style/:filename"}
마지막으로 클립 모델에서 :
has_attached_file :image, {
:styles => {:thumb => '50x50#', :original => '800x800>'}
}.merge(PAPERCLIP_STORAGE_OPTIONS)
업데이트 : 최근 Rails 3.x 앱용 Paperclip에서 유사한 접근 방식이 구현되었습니다 . 이제 환경 별 설정을 config.paperclip_defaults = {:storage => :s3, ...}
.
환경 별 구성 파일에서 전역 기본 구성 데이터를 설정할 수 있습니다. 예를 들어, config / environments / production.rb에서 :
Paperclip::Attachment.default_options.merge!({
:storage => :s3,
:bucket => 'wheresmahbucket',
:s3_credentials => {
:access_key_id => ENV['S3_ACCESS_KEY_ID'],
:secret_access_key => ENV['S3_SECRET_ACCESS_KEY']
}
})
한동안 가지고 놀다가 내가 원하는 것을하는 모듈을 생각 해냈다.
내부 app/models/shared/attachment_helper.rb
:
module Shared
module AttachmentHelper
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def has_attachment(name, options = {})
# generates a string containing the singular model name and the pluralized attachment name.
# Examples: "user_avatars" or "asset_uploads" or "message_previews"
attachment_owner = self.table_name.singularize
attachment_folder = "#{attachment_owner}_#{name.to_s.pluralize}"
# we want to create a path for the upload that looks like:
# message_previews/00/11/22/001122deadbeef/thumbnail.png
attachment_path = "#{attachment_folder}/:uuid_partition/:uuid/:style.:extension"
if Rails.env.production?
options[:path] ||= attachment_path
options[:storage] ||= :s3
options[:url] ||= ':s3_authenticated_url'
options[:s3_credentials] ||= File.join(Rails.root, 'config', 's3.yml')
options[:s3_permissions] ||= 'private'
options[:s3_protocol] ||= 'https'
else
# For local Dev/Test envs, use the default filesystem, but separate the environments
# into different folders, so you can delete test files without breaking dev files.
options[:path] ||= ":rails_root/public/system/attachments/#{Rails.env}/#{attachment_path}"
options[:url] ||= "/system/attachments/#{Rails.env}/#{attachment_path}"
end
# pass things off to paperclip.
has_attached_file name, options
end
end
end
end
(참고 : 위의 일부 사용자 지정 클립 보간 (예 : :uuid_partition
, :uuid
및)을 사용하고 :s3_authenticated_url
있습니다. 특정 응용 프로그램에 필요한 사항을 수정해야합니다.)
이제 종이 클립 첨부 파일이있는 모든 모델에 대해이 공유 모듈을 포함하고 has_attachment
메서드를 호출하면 됩니다 (paperclip 대신 has_attached_file
).
예제 모델 파일 : app/models/user.rb
:
class User < ActiveRecord::Base
include Shared::AttachmentHelper
has_attachment :avatar, :styles => { :thumbnail => "100x100>" }
end
이렇게하면 환경에 따라 다음 위치에 파일이 저장됩니다.
개발:
RAILS_ROOT + public/attachments/development/user_avatars/aa/bb/cc/aabbccddeeff/thumbnail.jpg
테스트:
RAILS_ROOT + public/attachments/test/user_avatars/aa/bb/cc/aabbccddeeff/thumbnail.jpg
생산:
https://s3.amazonaws.com/your-bucket-name/user_avatars/aa/bb/cc/aabbccddeeff/thumbnail.jpg
이것은 내가 찾고있는 것을 정확히 수행하며, 다른 사람에게도 유용 할 것입니다. :)
-남자
이것은 어떤가요:
- 기본값은 application.rb에 설정됩니다. : filesystem의 기본 저장소가 사용되지만 s3에 대한 구성이 초기화됩니다.
- Production.rb는 : s3 스토리지를 활성화하고 기본 경로를 변경합니다.
Application.rb
config.paperclip_defaults =
{
:hash_secret => "LongSecretString",
:s3_protocol => "https",
:s3_credentials => "#{Rails.root}/config/aws_config.yml",
:styles => {
:original => "1024x1024>",
:large => "600x600>",
:medium => "300x300>",
:thumb => "100x100>"
}
}
Development.rb (개발 모드에서 s3로 시도하려면 주석 처리를 제거하십시오)
# config.paperclip_defaults.merge!({
# :storage => :s3,
# :bucket => "mydevelopmentbucket",
# :path => ":hash.:extension"
# })
Production.rb :
config.paperclip_defaults.merge!({
:storage => :s3,
:bucket => "myproductionbucket",
:path => ":hash.:extension"
})
모델에서 :
has_attached_file :avatar
production / test / development.rb에서 환경 변수를 설정할 수 없습니까?
PAPERCLIP_STORAGE_MECHANISM = :s3
그때:
has_attached_file :image, :styles => {...},
:storage => PAPERCLIP_STORAGE_MECHANISM,
# ...etc...
내 솔루션은 @runesoerensen 답변과 동일합니다.
나는 모듈 생성 PaperclipStorageOption
의 config/initializers/paperclip_storage_option.rb
코드는 매우 간단합니다 :
module PaperclipStorageOption
module ClassMethods
def options
Rails.env.production? ? production_options : default_options
end
private
def production_options
{
storage: :dropbox,
dropbox_credentials: Rails.root.join("config/dropbox.yml")
}
end
def default_options
{}
end
end
extend ClassMethods
end
우리 모델에서 사용 has_attached_file :avatar, { :styles => { :medium => "1200x800>" } }.merge(PaperclipStorageOption.options)
Just it, hope this help
Use the :rails_env interpolation when you define the attachment path:
has_attached_file :attachment, :path => ":rails_root/storage/:rails_env/attachments/:id/:style/:basename.:extension"
'program tip' 카테고리의 다른 글
프로그래밍 방식으로 android : animateLayoutChanges 설정 (0) | 2020.10.19 |
---|---|
git gc --aggressive vs git repack (0) | 2020.10.19 |
두 개 이상의 공백과 일치하지만 새 줄은 일치하지 않는 정규식 (0) | 2020.10.19 |
연속 메모리가있는 C ++ 벡터에 해당하는 C #? (0) | 2020.10.19 |
Java Collections singletonMap 메소드는 언제 사용합니까? (0) | 2020.10.19 |