2016-05-11 34 views
4

我有圖片模型,它將整個應用程序中的圖片存儲在可成像列中,我存儲Image owner對象。我希望能夠以不同的分辨率保存這些圖片。Rails 4.2.6 + Polymorphic + Carrierwave 0.10 + conditions

class Picture < AbstractModel 
    belongs_to :imageable, polymorphic: true 
    mount_uploader :image, ImageUploader 
end 

class User < AbstractModel 
    has_one :picture, class_name: Picture, as: :imageable, dependent: :destroy 
    accepts_nested_attributes_for :picture 
end 

class Event < AbstractModel 
    has_one :picture, class_name: Picture, as: :imageable, dependent: :destroy 
    accepts_nested_attributes_for :picture 
end 

在Carrierwave我做了

class ImageUploader < CarrierWave::Uploader::Base 
    version :xs if: :for_user? do 
    process resize_to_fit: [100, 100] 
    end 

    private 

    def for_user?(_picture) 
     # And here I hit the problem! 
     # model.is_a? User 
    end 
end 

我怎麼可以在這裏獲取圖片所有者模式?

modelPicture模型的變量引用,我試過所有的變量與pry,但沒有成功。

當然,我可以在這段代碼中直接在用戶和事件中存儲圖像鏈接,但在真實世界的代碼中,我有大約15個不同的模型使用圖像,我必須提供在ActiveAdmin CMS中編輯它的能力(但它是另一個故事:)

UPDATE

主要的問題發生了,當我創造新的紀錄。所以,我試圖添加inverse_of,但它沒有幫助。

class Picture < AbstractModel 
    belongs_to :imageable, polymorphic: true, inverse_of: :pictures 
    mount_uploader :image, ImageUploader 

class User < AbstractModel 
    has_one :picture, class_name: Picture, as: :imageable, dependent: :destroy, inverse_of: :imageable 
    accepts_nested_attributes_for :picture 

這裏是for_user?方法

[5] pry(#<ImageUploader>)> ap model 
Изображение для { 
       :id => nil, 
      :image => #<ImageUploader:0x005583dee8f938 @model=#<Picture id: nil, image: nil, imageable_id: nil, imageable_type: nil, created_at: nil, updated_at: nil>, @mounted_as=:image, @cache_id="1463023347-21567-5096", @filename="rootp_HE_pause-20160113_141810.jpg", @original_filename="rootp_HE_pause-20160113_141810.jpg", @file=#<CarrierWave::SanitizedFile:0x005583dee8cf30 @file="/home/kvokka/proj/volunteers/public/uploads/tmp/1463023347-21567-5096/rootp_HE_pause-20160113_141810.jpg", @original_filename=nil, @content_type="image/jpeg">, @versions={:mini=>#<ImageUploader::Uploader47012442238420:0x005583dee724a0 @model=#<Picture id: nil, image: nil, imageable_id: nil, imageable_type: nil, created_at: nil, updated_at: nil>, @mounted_as=:image>, :xs=>#<ImageUploader::Uploader47012435752020:0x005583dee72450 @model=#<Picture id: nil, image: nil, imageable_id: nil, imageable_type: nil, created_at: nil, updated_at: nil>, @mounted_as=:image>, :avatar=>#<ImageUploader::Uploader47012437005860:0x005583dee72428 @model=#<Picture id: nil, image: nil, imageable_id: nil, imageable_type: nil, created_at: nil, updated_at: nil>, @mounted_as=:image>}>, 
     :imageable_id => nil, 
    :imageable_type => nil, 
     :created_at => nil, 
     :updated_at => nil 

UPDATE2

我已經與inverse_of thried的model狀態:圖片與inverse_of:圖片。語法錯誤。它使用inverse_of :::imageable運行,但結果相同。

ImageUploader的

最新版本(我剪了爲簡潔)是

class ImageUploader < CarrierWave::Uploader::Base 
    version :xs do 
    process resize_to_fit: [100, 100] 
    end 

    version :avatar, if: :for_user? do 
    process resize_to_fit: [360, 360] 
    end 

    private 

    def for_user?(_) 
     model.imageable.is_a? User 
    end 
end 

UPDATE3

我做了一些控制檯的動作,所以你可以看到,該模型接受嵌套屬性。在has_one關係的情況下,它也沒有#inverse_of方法(並且這個時刻對我來說很棘手)。因此,日誌:

[43] pry(main)> ap v = VolunteerCenter.create(title: 'tst', address:'tst', city: City.first, phone:'123456',email: '[email protected]', description: 'ololo', link: 'http://ddd.ru', picture: (Picture.new(remote_image_url: 'https://retina.news.mail.ru/prev780x440/pic/e5/35/image25749462_adfc024a9b54b718c1a755445661b099.jpg'))) 
    City Load (0.8ms) SELECT "cities".* FROM "cities" ORDER BY "cities"."id" ASC LIMIT 1 
    (0.2ms) BEGIN 
    SQL (0.4ms) INSERT INTO "volunteer_centers" ("title", "address", "city_id", "phone", "email", "description", "link", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING "id" [["title", "tst"], ["address", "tst"], ["city_id", 1], ["phone", "123456"], ["email", "[email protected]"], ["description", "ololo"], ["link", "http://ddd.ru"], ["created_at", "2016-05-12 12:13:44.417945"], ["updated_at", "2016-05-12 12:13:44.417945"]] 
    SQL (0.3ms) INSERT INTO "pictures" ("image", "imageable_type", "imageable_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["image", "image25749462_adfc024a9b54b718c1a755445661b099.jpg"], ["imageable_type", "VolunteerCenter"], ["imageable_id", 11], ["created_at", "2016-05-12 12:13:44.421458"], ["updated_at", "2016-05-12 12:13:44.421458"]] 
    (2.2ms) COMMIT 
tst { 
      :id => 11, 
      :title => "tst", 
    :created_at => Thu, 12 May 2016 12:13:44 UTC +00:00, 
    :updated_at => Thu, 12 May 2016 12:13:44 UTC +00:00, 
     :address => "tst", 
     :city_id => 1, 
      :phone => "123456", 
      :email => "[email protected]", 
    :description => "ololo", 
     :vk_link => nil, 
      :link => "http://ddd.ru" 
} 
=> nil 
[44] pry(main)> ap v.picture 
    VolunteerCenter Load (0.6ms) SELECT "volunteer_centers".* FROM "volunteer_centers" WHERE "volunteer_centers"."id" = $1 LIMIT 1 [["id", 11]] 
Изображение для tst { 
       :id => 120, 
      :image => #<ImageUploader:0x0055596544d928 @model=#<Picture id: 120, image: "image25749462_adfc024a9b54b718c1a755445661b099.jpg", imageable_id: 11, imageable_type: "VolunteerCenter", created_at: "2016-05-12 12:13:44", updated_at: "2016-05-12 12:13:44">, @mounted_as=:image, @cache_id=nil, @filename="image25749462_adfc024a9b54b718c1a755445661b099.jpg", @original_filename="image25749462_adfc024a9b54b718c1a755445661b099.jpg", @file=#<CarrierWave::SanitizedFile:0x00555963f0c690 @file="/home/kvokka/proj/volunteers/public/uploads/picture/image/120/image25749462_adfc024a9b54b718c1a755445661b099.jpg", @original_filename=nil, @content_type="image/jpeg">, @versions={:mini=>#<ImageUploader::Uploader46921211280280:0x00555966c55890 @model=#<Picture id: 120, image: "image25749462_adfc024a9b54b718c1a755445661b099.jpg", imageable_id: 11, imageable_type: "VolunteerCenter", created_at: "2016-05-12 12:13:44", updated_at: "2016-05-12 12:13:44">, @mounted_as=:image, @parent_cache_id="1463055224-8966-4735", @cache_id=nil, @filename="image25749462_adfc024a9b54b718c1a755445661b099.jpg", @original_filename="image25749462_adfc024a9b54b718c1a755445661b099.jpg", @file=#<CarrierWave::SanitizedFile:0x00555966e89620 @file="/home/kvokka/proj/volunteers/public/uploads/picture/image/120/mini_image25749462_adfc024a9b54b718c1a755445661b099.jpg", @original_filename=nil, @content_type="image/jpeg">, @versions={}, @storage=#<CarrierWave::Storage::File:0x00555966e8a4a8 @uploader=#<ImageUploader::Uploader46921211280280:0x00555966c55890 ...>>>, :xs=>#<ImageUploader::Uploader46921211274220:0x00555966c55868 @model=#<Picture id: 120, image: "image25749462_adfc024a9b54b718c1a755445661b099.jpg", imageable_id: 11, imageable_type: "VolunteerCenter", created_at: "2016-05-12 12:13:44", updated_at: "2016-05-12 12:13:44">, @mounted_as=:image, @parent_cache_id="1463055224-8966-4735", @cache_id=nil, @filename="image25749462_adfc024a9b54b718c1a755445661b099.jpg", @original_filename="image25749462_adfc024a9b54b718c1a755445661b099.jpg", @file=#<CarrierWave::SanitizedFile:0x005559659d60c0 @file="/home/kvokka/proj/volunteers/public/uploads/picture/image/120/xs_image25749462_adfc024a9b54b718c1a755445661b099.jpg", @original_filename=nil, @content_type="image/jpeg">, @versions={}, @storage=#<CarrierWave::Storage::File:0x005559659d7010 @uploader=#<ImageUploader::Uploader46921211274220:0x00555966c55868 ...>>>, :avatar==>#<ImageUploader::Uploader46921211257860:0x00555966c55840 @model=#<Picture id: 120, image: "image25749462_adfc024a9b54b718c1a755445661b099.jpg", imageable_id: 11, imageable_type: "VolunteerCenter", created_at: "2016-05-12 12:13:44", updated_at: "2016-05-12 12:13:44">, @mounted_as=:image, @parent_cache_id="1463055224-8966-4735", @cache_id=nil, @filename="image25749462_adfc024a9b54b718c1a755445661b099.jpg", @original_filename="image25749462_adfc024a9b54b718c1a755445661b099.jpg", @file=#<CarrierWave::SanitizedFile:0x00555963379328 @file="/home/kvokka/proj/volunteers/public/uploads/picture/image/120/avatar=_image25749462_adfc024a9b54b718c1a755445661b099.jpg", @original_filename=nil, @content_type="image/jpeg">, @versions={}, @storage=#<CarrierWave::Storage::File:0x0055596337a390 @uploader=#<ImageUploader::Uploader46921211257860:0x00555966c55840 ...>>>}, @storage=#<CarrierWave::Storage::File:0x00555965d85fb8 @uploader=#<ImageUploader:0x0055596544d928 ...>>>, 
     :imageable_id => 11, 
    :imageable_type => "VolunteerCenter", 
     :created_at => Thu, 12 May 2016 12:13:44 UTC +00:00, 
     :updated_at => Thu, 12 May 2016 12:13:44 UTC +00:00 
} 

UPDATE4

,當我在回調方法撬運行此happents。

class ImageUploader < CarrierWave::Uploader::Base 
    version :avatar, if: :for_user? do 
    puts 'This line never run' 
    process resize_to_fit: [360, 360] 
    end 

    private 

    def for_user?(picture) 
     binding.pry 
     model.imageable.is_a? User 
    end 

我關閉所有驗證以進行澄清。 該回調被調用3次,並且在前2個User實例未準備好,並且在最後一個回調不起作用之後。

[46] pry(main)> ap u = User.create(email: '[email protected]', password: '123456', password_confirmation: '123456', picture: (Picture.create remote_image_url: 'http://onrails.club/uploads/default/29/31f7627609164af8.png')) 

From: /home/kvokka/proj/volunteers/app/uploaders/image_uploader.rb @ line 68 ImageUploader#for_user?: 

    66: def for_user?(_) 
    67: binding.pry 
=> 68: model.imageable.is_a? User 
    69: end 

@cache_id    "1463060913-8966-3349" 
@file     #<CarrierWave::SanitizedFile:0x00555963268330 @file="/hom... 
@filename    "31f7627609164af8.png" 
@model     #<Picture id: nil, image: nil, imageable_id: nil, imageab... 
@mounted_as    :image 
@original_filename  "31f7627609164af8.png" 
@versions    {:mini=>#<ImageUploader::Uploader46921199022860:0x0055596... 
[1] pry(#<ImageUploader>)> 

From: /home/kvokka/proj/volunteers/app/uploaders/image_uploader.rb @ line 68 ImageUploader#for_user?: 

    66: def for_user?(_) 
    67: binding.pry 
=> 68: model.imageable.is_a? User 
    69: end 

@cache_id    "1463060913-8966-3349" 
@file     #<CarrierWave::SanitizedFile:0x00555963268330 @file="/hom... 
@filename    "31f7627609164af8.png" 
@model     #<Picture id: nil, image: nil, imageable_id: nil, imageab... 
@mounted_as    :image 
@original_filename  "31f7627609164af8.png" 
@versions    {:mini=>#<ImageUploader::Uploader46921199022860:0x0055596... 
[1] pry(#<ImageUploader>)> 
    (0.3ms) BEGIN 
    SQL (0.7ms) INSERT INTO "pictures" ("image", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["image", "31f7627609164af8.png"], ["created_at", "2016-05-12 13:48:40.071387"], ["updated_at", "2016-05-12 13:48:40.071387"]] 

From: /home/kvokka/proj/volunteers/app/uploaders/image_uploader.rb @ line 68 ImageUploader#for_user?: 

    66: def for_user?(_) 
    67: binding.pry 
=> 68: model.imageable.is_a? User 
    69: end 

@cache_id    nil 
@file     #<CarrierWave::SanitizedFile:0x005559639c6348 @file="/hom... 
@filename    "31f7627609164af8.png" 
@model     #<Picture id: 112, image: "31f7627609164af8.png", imageab... 
@mounted_as    :image 
@original_filename  "31f7627609164af8.png" 
@storage     #<CarrierWave::Storage::File:0x00555963b5add0 @uploader=#... 
@versions    {:mini=>#<ImageUploader::Uploader46921199022860:0x0055596... 
[1] pry(#<ImageUploader>)> 
    (2.9ms) COMMIT 
    (0.2ms) BEGIN 
    User Exists (0.7ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = '[email protected]' LIMIT 1 
    SQL (0.4ms) INSERT INTO "users" ("email", "encrypted_password", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["email", "[email protected]"], ["encrypted_password", "$2a$11$qq8tVgzISJguKz7oVJWyVO45vW/ujSEsi/ow29w78nC9ByOdjrPYK"], ["created_at", "2016-05-12 13:48:41.761836"], ["updated_at", "2016-05-12 13:48:41.761836"]] 
    SQL (0.4ms) UPDATE "pictures" SET "imageable_type" = $1, "imageable_id" = $2, "updated_at" = $3 WHERE "pictures"."id" = $4 [["imageable_type", "User"], ["imageable_id", 31], ["updated_at", "2016-05-12 13:48:41.764681"], ["id", 112]] 
    (2.7ms) COMMIT 
, { 
          :id => 31, 
         :email => "[email protected]", 
      :encrypted_password => "$2a$11$qq8tVgzISJguKz7oVJWyVO45vW/ujSEsi/ow29w78nC9ByOdjrPYK", 
     :reset_password_token => nil, 
     :reset_password_sent_at => nil, 
      :remember_created_at => nil, 
       :sign_in_count => 0, 
      :current_sign_in_at => nil, 
       :last_sign_in_at => nil, 
      :current_sign_in_ip => nil, 
       :last_sign_in_ip => nil, 
        :created_at => Thu, 12 May 2016 13:48:41 UTC +00:00, 
        :updated_at => Thu, 12 May 2016 13:48:41 UTC +00:00, 
         :name => nil, 
         :surname => nil, 
         :phone => nil, 
          :dob => nil, 
         :gender => nil, 
         :height => nil, 
         :about => nil, 
     :information_source_id => nil, 
       :institution_id => nil, 
       :clothes_size_id => nil, 
         :city_id => nil, 
      :volunteer_center_id => nil, 
        :blood_id => nil, 
       :vkontakte_link => nil, 
    :medical_contraindications => nil 
} 
=> nil 

的問題仍然是開放的

回答

0

我怎麼可以在這裏獲取圖片所有者模式?

假設你指的是用戶記錄,當你說「圖片所有者模式」,那麼你可以做以下

class ImageUploader < CarrierWave::Uploader::Base 
    ... 
    def for_user?(picture) 
    user = model.imageable 
    user.is_a? User 
    # => true 
    end 
    ... 
end 

docs

  • picture參數正在上傳的文件對象(這不是您的Picture模型的實例)

  • model是對您使用此實例對象的引用ImageUploader,在您的案例中引用的是Picture模型的實例。請注意,這與上面的picture不同。

現在你知道modelPicture一個實例,並且Picture belongs_to :imageable,那:imageable是一個多態協會實際上是在你的情況下User記錄,那麼你可以用我的回答訪問上述相關記錄。但請注意,它可能並不總是User記錄,因爲它是一個多態關聯。

UPDATE

我猜model.imageable不工作,因爲成像記錄是零,從嵌套PARAMS正在建立之後。

你可以嘗試

class Picture < AbstractModel 
    belongs_to :imageable, polymorphic: true, inverse_of: :picture # WITHOUT s 

UPDATE

看起來inverse_of不與多態關聯(herehere

有一些限制inverse_of支持工作:

  • 它們不適用於:通過關聯。
  • 它們不適用於:多態關聯。
  • 他們不與:作爲協會。
  • 對於belongs_to關聯,忽略has_many反向關聯。

P.S.這可能會很棘手。如果我有時間,我會盡力重現這個問題。

+0

謝謝,但它沒有幫助。我已經更新了這個問題並添加了一些細節,所以它可能會有用。你的想法只會分叉更新圖像,對於新的我會捕獲所有版本。 –

+0

我更新了我的答案。你可以嘗試,如果它會工作? –

+0

謝謝。我已經結婚了:照片和照片。語法錯誤。它使用inverse_of :::imageable運行,但結果相同。 –