使用include中嵌Hash取出一個多層次的對象關聯數據

使用include中嵌Hash取出一個多層次的對象關聯數據.

首先有如下關係:

project issue : 一對多
issue comment : 一對多
comment history : 一對多
Project [1] <---- [n] issue (1) <---- (n) comment [1] <---- [n] history



class Project
has_many :issues
end



class Issue
belongs_to :project
has_many :cccc # cccc 爲了區別後面的名稱不致混淆

#在issue中創建一條與之對應的comment,這裏用實例變量爲了方便在issue保存的時候也一同保存comment的信息。
def init_comment(content = "")
@current_comment ||= Comment.new(:resource => self, :creater => current_user, :content => content)
@issue_before_change = self.clone
@current_comment
end

#issue保存的時候一同保存comment,以及histories的信息。
##這裏需要注意的是,要保證histories表中的comment_id(histories表中與comment關聯的外鍵) `comment_id` int(11) default '0', 必需設置一個默認值,否則將不能保存comment 和 history的信息。
def before_save
if @current_comment
# attributes changes
(Issue.column_names - %w(id content resource_id resource_type)).each {|c|
@current_comment.histories << History.new(:property=>c,
:comment => @current_comment,
:old_value => @issue_before_change.send(c),
:value => send(c)) unless send(c)==@issue_before_change.send(c)
}
@current_comment.save
end
# Save the issue even if the comment is not saved (because empty)
true
end

end



class Comment
belongs_to :issue
has_many :histories
end



class History
belongs_to :comment
end


一條語句實現取出這其中的所有記錄:

Project.find(:first,:include =>[{ :issue => { :cccc => { :histories => :comment }}}]
注意,include中的關聯的名稱要對應好。



API 中的相關使用介紹
To include a deep hierarchy of associations, use a hash:

for post in Post.find(:all, :include => [ :author, { :comments => { :author => :gravatar } } ])

That‘ll grab not only all the comments but all their authors and gravatar pictures. You can mix and match symbols, arrays and hashes in any combination to describe the associations you want to load.

All of this power shouldn‘t fool you into thinking that you can pull out huge amounts of data with no performance penalty just because you‘ve reduced the number of queries. The database still needs to send all the data to Active Record and it still needs to be processed. So it‘s no catch-all for performance problems, but it‘s a great way to cut down on the number of queries in a situation as the one described above.

Since the eager loading pulls from multiple tables, you‘ll have to disambiguate any column references in both conditions and orders. So :order => "posts.id DESC" will work while :order => "id DESC" will not. Because eager loading generates the SELECT statement too, the :select option is ignored.

You can use eager loading on multiple associations from the same table, but you cannot use those associations in orders and conditions as there is currently not any way to disambiguate them. Eager loading will not pull additional attributes on join tables, so "rich associations" with has_and_belongs_to_many are not a good fit for eager loading.

When eager loaded, conditions are interpolated in the context of the model class, not the model instance. Conditions are lazily interpolated before the actual model exists.

發佈了8 篇原創文章 · 獲贊 0 · 訪問量 2631
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章