2012-11-22 33 views
1

這裏我的模型:Rails 3中,HAS_ONE /的has_many與拉姆達條件

class User < ActiveRecord::Base 
    has_many :bookmarks 
end 

class Topic < ActiveRecord::Base 
    has_many :bookmarks 
end 

class Bookmark < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :topic 
    attr_accessible :position 
    validates_uniqueness_of :user_id, :scope => :topic_id 
end 

我想獲取所有topics用,爲current_user,相關bookmark。 ATM,我這樣做:

Topic.all.each do |t| 
    bookmark = t.bookmarks.where(user_id: current_user.id).last 
    puts bookmark.position if bookmark 
    puts t.name 
end 

這是醜陋的,做太多的數據庫查詢。我想這樣的事情:

class Topic < ActiveRecord::Base 
    has_one :bookmark, :conditions => lambda {|u| "bookmarks.user_id = #{u.id}"} 
end 

Topic.includes(:bookmark, current_user).all.each do |t| # this must also includes topics without bookmark 
    puts t.bookmark.position if t.bookmark 
    puts t.name 
end 

這可能嗎?我有其他選擇嗎?

謝謝!

回答

6

*嗯,我不知道我理解你的問題,但是這可能會幫助您:

# code 
class Topic < ActiveRecord::Base 
    scope :for_user, lambda { |user| includes(:bookmarks).where(bookmarks: { user_id: user.try(:id) || user}) } 

# call 
Topic.for_user(current_user) # => Array of Topics 

正如你可以看到範圍的參數for_user可以是用戶對象或用戶ID

希望這會有所幫助!

類似的問題:

+1

'includes'排除unbookmarked'topics'。根據你的想法,我將它改爲'joins':'scope:for_user,lambda {| user |選擇('topics。*,bookmarks.position as position).joins(「LEFT JOIN bookmarks ON bookmarks.topic_id = topics.id AND bookmarks.user_id =#{user.try(:id)|| user}」)}' 。 然後在代碼中:'''Topic.for_user(current_user)'。 '連接'似乎不是默認選擇屬性。我正在尋找更清潔的解決方案,但它的工作。謝謝 :) – Habax