使用未知数据过滤rails模型

时间:2011-10-16 01:03:03

标签: ruby-on-rails filter

我正在使用以下代码获取特定用户的打开存储桶列表。

@open_buckets = Buckets.order("buckets.id ASC").where(:user_id => @user.id)

用户还有一个私有桶的概念。我只希望在登录用户是存储桶的所有者时返回私有存储桶。私有字段是布尔值。我可以以某种方式更改我的查询,以便所有用户获得公共存储桶,只有业主获得他们的私人存储桶和公共存储桶?

我唯一想到的是检查登录用户是否与请求存储桶的用户相同并执行不同的查询。像下面的东西。

if :session["user_id"] => :user_id
    @open_buckets = Buckets.order("buckets.id ASC").where(:user_id => @user_id)
else
    @open_buckets = Buckets.order("buckets.id ASC").where(:user_id => @user_id).where(:private => true)

由于

2 个答案:

答案 0 :(得分:2)

好吧,虽然我不同意使用一个视图(或一个列表/部分,更具体地说)来显示两种不同类型的信息,但这里有一种方法可以做你想要的:

@buckets = Buckets.order("buckets.id ASC").where(:user_id => @user_id, :private => false)
@buckets += @buckets.where(:private => true) if current_user.id == user.id

您还可以创建一些很酷的范围来处理模型中的这个半复杂逻辑,它应该是,并且还可以更充分地利用您的关联:

@user = User.find(params[:user_id])
@buckets = @user.buckets.public
@buckets += @user.buckets.private if @current_user == @user
respond_with @buckets = @buckets.order("buckets.id asc")

Buckets型号:

scope :public, where(:private => false)
scope :private, where(:private => true)

作为旁注,模型类名称应该始终是单数。您的示例中有Buckets,所以如果这不是拼写错误,那么我建议您返回并更改它,如果这样做是可行的。它会引起混乱,特别是对于您应用程序的未来开发人员。

答案 1 :(得分:0)

named_scope(或只是scope in Rails 3)可以做到。

class Bucket
  ...

  named_scope :visible_buckets_for, lambda {|user| { :conditions=>["private = 'f' OR (private = 't' and user_id = ?)", current_user.id], :order=>"buckets.id ASC" } }

其中'current_user'是您必须检索当前登录用户的id的任何方法,而't'true值的特定于数据库的表示。某些DB使用“true”或任何非零数字。

然后你称之为:

 > Bucket.visible_buckets_for(current_user)
=> [<#Bucket1>, <#Bucket2>, <#Bucket3> ... ]

...这是Bucket个对象的数组,按id排序。

您可以将任何用户传递到该命名范围,以防您需要查找的不仅仅是当前用户。