向现有的named_scope添加另一个条件

时间:2011-06-29 02:41:59

标签: ruby-on-rails ruby scope

我正在研究Rails 2.3.9应用程序,我的问题涉及自我参照关系和named_scope。此应用程序允许用户记录和共享锻炼。锻炼可以是公共的或私人的,由@workout.public == 1指定。

我允许用户“关注”他人。因此,在current_user的仪表板上,我显示来自用户的所有公共训练,其中current_user遵循以下代码:

/dashboard/index.html.erb

 <% current_user.friends_workouts.each do |workout| %>
  <%= link_to (workout.title), workout %> <br/>
  by <%= link_to (workout.user.username), workout.user %> - <%= time_ago_in_words(workout.created_at)%> ago</p>
 <% end %>

user.rb

def friends_workouts
 @friends_workouts ||= Workout.current.public_workouts.find_all_by_user_id(self.friends.map(&:id), :order =>  "created_at DESC", :limit => 3)
end

workout.rb

named_scope :public_workouts, :conditions => {:public => 1 }, :order => "created_at DESC"

我现在想要添加一个条件到这个范围,因为我正在添加另一个级别的共享。用户可以通过“会员”模型与“盒子”(真正的健身房)相关联。因此,如果current_user属于与他们关注的用户相同的“框”,他们不仅应该看到标记为公开的锻炼,还应该看到@workout.box_only == 1的锻炼。

如何影响上述内容,以包括来自跟随的用户和@workout.box_only == 1 and @workout.user.membership.box_id == current_user.membership.box_id后续用户的所有公开训练。我知道语法不正确,但你明白我的观点(希望如此)。

更新:

还需要考虑:从不需要logged_in的页面调用public_workouts?用户所以在这种情况下,如果范围试图引用current_user,它将引发错误。

更新2: :用户has_many:成员资格

1 个答案:

答案 0 :(得分:0)

我相信以下内容应该适合你:

named_scope :public_workouts, 
            :joins => ", user, membership"
            :conditions => 
              "workouts.public = 1 or
               membership.box_id = #{current_user.membership.box_id}",
            :group => "workouts.id",
            :order => "workouts.created_at DESC"

你必须稍微玩一下这个。每次尝试这样的事情时,困难的部分就是让OR条件正确。您希望公开所有公开以及加入的membership.box_id匹配的内容,无论公众是否为1。

编辑:不可否认,这可能不是构建查询的最红宝石方式,我还没有正确测试它,但下面的内容也可以使用。

def self.public_workouts
  query = Workout.joins(:user => { :membership })
  if current_user
    query.where('memberships.box_id = ? or workouts.public = 1', current_user.membership.box_id) unless current_user.membership.box_id.nil?
  else
    query.where('workouts.public = 1')
  end
  query.group('workouts.id')
  query.order("workouts.created_at DESC")
  return query
end

<强> EDIT2 另一种方法是创建两个单独的范围并创建一个组合两个范围的类方法。然后将在视图中使用此类方法。

named_scope :box_workouts, 
            :joins => ", user, membership"
            :conditions => "memberships.box_id = #{current_user.membership.box_id}"
            :group => "workouts.id",
            :order => "workouts.created_at DESC",
            :select "workouts"

named_scope :public_workouts, 
            :conditions => :public => 1
            :order => "workouts.created_at DESC"    

def self.public_box_workouts
  return box_workouts.merge(public_workouts).limit(3) if current_user
  return public_workouts.limit(3)
end     

编辑3 不是那么难,我相信下面的内容会起作用。

def self.box_and_public_workouts(user)
  return public_workouts if user.nil? or user.memberships.blank?
  return public_workouts + box_workouts(user.memberships.map(&:box_id))
end

named_scope :box_workouts, lambda { |box_ids| { :conditions => ['box_id IN (?)', box_ids], :order => 'created_at DESC' } }

抱歉这么久。我不知道如何查询数据库的“旧”方式。我选择了Rails3:)

无论如何,我不想做任何事情,所以我试图分叉它发送一个拉请求,但github今晚对我很粗鲁。可能只是从这里复制。