Ruby on rails 将另一个条件添加到现有命名范围
我正在开发一个Rails 2.3.9应用程序,我的问题涉及到一个自我引用关系和一个命名的_范围。此应用程序允许用户记录和共享训练。训练可以是公共的,也可以是私人的,由@workout.public==1指定 我允许用户“跟踪”用户。因此,在当前用户的仪表板上,我显示当前用户遵循的所有公共训练,代码如下: /dashboard/index.html.erbRuby on rails 将另一个条件添加到现有命名范围,ruby-on-rails,ruby,scope,Ruby On Rails,Ruby,Scope,我正在开发一个Rails 2.3.9应用程序,我的问题涉及到一个自我引用关系和一个命名的_范围。此应用程序允许用户记录和共享训练。训练可以是公共的,也可以是私人的,由@workout.public==1指定 我允许用户“跟踪”用户。因此,在当前用户的仪表板上,我显示当前用户遵循的所有公共训练,代码如下: /dashboard/index.html.erb <% current_user.friends_workouts.each do |workout| %> <%= l
<% 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 %>
workout.rb
named_scope :public_workouts, :conditions => {:public => 1 }, :order => "created_at DESC"
现在,我想向这个范围添加一个条件,因为我正在添加另一个级别的共享。用户可以通过一个会员模型将一个盒子和一个健身房联系起来。因此,如果当前用户与他们关注的用户属于同一个框,那么他们不仅应该看到标记为public的训练,还应该看到@workout.box\u only==1的训练
我如何影响上述内容,以包括所有来自跟踪用户的公共训练以及来自跟踪用户的训练,其中@count.box\u only==1和@count.user.membership.box\u id==current\u user.membership.box\u id。我知道语法不正确,但希望您能理解我的观点
更新:
还需要考虑的是:公共训练是从不需要登录的页面调用的?因此,在这种情况下,如果作用域试图引用当前用户,它将抛出一个错误
更新2:
:user拥有许多:会员资格我相信下面这样的东西可以帮你做到:
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"
你得玩一会儿这个。每次我尝试这样的事情时,最困难的部分就是要得到正确的条件。您希望获取所有public以及joined membership.box_id匹配的那些,而不考虑public为1
编辑:不可否认,这可能不是构建查询的最简单的ruby方式,我还没有对其进行适当的测试,但下面类似的东西也可以使用
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
编辑2
另一种选择是创建两个单独的作用域,并创建一个组合这两个作用域的类方法。然后在视图中使用该类方法
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
Edit3没那么难,我相信下面的方法会奏效
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' } }
抱歉花了这么长时间。我对查询数据库的旧方法感到困惑。我直奔铁路3:
无论如何,我不想做任何事情,所以我尝试用叉子发送拉请求,但github今晚对我很粗鲁。那就从这里抄吧。好的,我还没试过,明天会的。另外,你知道我会如何限制会员资格,并且当有人登录时,只启动一部分框吗?当public_训练查找当前_用户时,我不想让未登录用户到处出错。有意义吗?添加了一个更丑陋的备选方案,可以让您处理当前未登录的用户。我知道这个查询有问题,但我想你明白我的意思了。好吧,现在试试这些看起来很棒。需要注意的是,公共箱训练还需要查找workout.box_only==1,而不仅仅是membership.id的匹配项。这些项似乎都无法实现,但这可能是我的错。我在问题中添加了一个更新,因为一个用户有很多会员资格,我不知道这是否会影响任何东西的语法,或者我们是否需要会员资格。首先还是什么。这就是问题所在:一个盒子有很多会员资格,一个用户可以有很多盒子,锻炼通过用户盒子会员资格属于一个盒子?
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' } }