2010-06-21 74 views
9

this question類似,如何在保存在此上下文之前在連接模型上設置屬性?Rails has_many:通過和設置加入屬性模型

class Post < ActiveRecord::Base 
    has_many :post_assets 
    has_many :assets, :through => :post_assets 
    has_many :featured_images, :through => :post_assets, :class_name => "Asset", :source => :asset, :conditions => ['post_assets.context = ?', "featured"] 

end 

class PostAssets < ActiveRecord::Base 
    belongs_to :post 
    belongs_to :asset 

    # context is so we know the scope or role 
    # the join plays 
    validates_presences_of :context 
end 

class Asset < ActiveRecord::Base 
    has_many :post_assets 
    has_many :posts, :through => :post_assets 
end 

我只是希望能夠做到這一點:

@post = Post.create!(:title => "A Post") 
@post.featured_images << Asset.create!(:title => "An Asset") 
# ... 
@post = Post.first 
@featured = @post.featured_images.first 
    #=> #<Asset id: 1, title: "An Asset"> 
@featured.current_post_asset #=> #<PostAsset id: 1, context: "featured"> 

如何將這項工作?我整天都在叮叮叮叮咚叨叨着:)。

目前發生的是當我這樣做:

@post.featured_images << Asset.create!(:title => "An Asset") 

然後加入時生成從來沒有得到一個機會來設置context模型PostAsset。我如何設置上下文屬性?它看起來像這樣:

PostAsset.first #=> #<PostAsset id: 1, context: nil> 

更新

我創建了一個測試gem,試圖找出問題。有沒有更簡單的方法來做到這一點?!

ActsAsJoinable::Core class使它可以在聯接模型中與它們之間的上下文有多對多的關係。它增加了輔助方法。基本tests顯示我正在嘗試做什麼。任何更好的想法如何正確地做到這一點?

+0

這也似乎類似於本星期早些時候我的問題: http://stackoverflow.com/questions/3035064/updating-extra-attributes-in-a-has-many-through-relationship-using-rails 我只是追溯地改變連接模型。然而,我認爲必須有回調才能在聯接模型保存前處理聯接模型。 +1',因爲我很好奇。 – Robbie 2010-06-21 02:40:31

+0

在非連接模型上有'before_add'和'after_add'回調(所以Post上的'assets'),但是如果不調用PostAsset.first(:conditions = > {...})'。在閱讀所有論壇後,它似乎是Rails中的一個缺失功能​​。 – 2010-06-21 03:42:14

回答

1

看在ActiveRecord的中的has_many選項::協會:: ClassMethods API位於:http://rails.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#M001316

這是最有趣的報價:

:條件

指定條件是相關聯的對象必須符合以便作爲WHERE SQL片段被包括,例如authorized = 1。如果使用散列,則來自關聯的記錄創建是範圍的。 has_many:posts,:conditions => {:published => true}將使用@ blog.posts.create或@ blog.posts.build創建發佈的帖子。

所以我相信你的條件必須被指定爲散列,像這樣:

class Post < ActiveRecord::Base 
    has_many :post_assets 
    has_many :featured_post_assets, :conditions => { :context => 'featured' } 

    has_many :assets, :through => :post_assets 

    has_many :featured_images, :through => :featured_post_assets, 
      :class_name => "Asset", :source => :asset, 
end 

而且你還應該做到以下幾點:的

@post.featured_images.build(:title => "An asset") 

代替:

@post.featured_images << Asset.create!(:title => "An Asset") 

這應該調用範圍內的資產構建,如第上面的引用將上下文字段添加到資產。它還會在一個原子事務中同時保存連接模型對象(post_asset)和資產對象到數據庫。

+0

這看起來應該可以工作。 – thomasfedb 2010-06-21 13:51:59

+0

那麼'@post.featured_images << Asset.first'和相關(不是實際建立/創建它)呢? – 2010-06-21 20:07:52

+0

我非常肯定,構建不會保存新記錄,直到@post對象被保存。 <<將在保存@post對象之前保存新對象,create將執行相同的操作。 – 2010-06-23 04:56:57

相關問題