首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >构造Rails ActiveRecord where子句

构造Rails ActiveRecord where子句
EN

Stack Overflow用户
提问于 2011-04-28 22:33:39
回答 5查看 24.9K关注 0票数 17

使用Rails ActiveRecord构造where子句的最佳方式是什么?例如,假设我有一个返回博客帖子列表的控制器操作:

代码语言:javascript
复制
def index
  @posts = Post.all
end

现在,假设我希望能够传递一个url参数,以便这个控制器操作只返回特定作者的帖子:

代码语言:javascript
复制
def index
  author_id = params[:author_id]

  if author_id.nil?
    @posts = Post.all
  else
    @posts = Post.where("author = ?", author_id)
  end
end

这对我来说并不是很枯燥。如果我要添加排序或分页,或者更糟的是,更多可选的URL查询字符串参数作为过滤依据,这个控制器操作将变得非常复杂。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-04-28 23:18:42

这样如何:

代码语言:javascript
复制
def index
  author_id = params[:author_id]

  @posts = Post.scoped

  @post = @post.where(:author_id => author_id) if author_id.present?

  @post = @post.where(:some_other_condition => some_other_value) if some_other_value.present?
end

Post.scoped本质上是一个延迟加载的等价于Post.all (因为Post.all立即返回一个数组,而Post.scoped只返回一个关系对象)。只有在视图中实际尝试迭代该查询(通过调用.each)之后,才会执行该查询。

票数 23
EN

Stack Overflow用户

发布于 2011-04-28 22:38:39

嗯,你想要使用的最好的方法可以是在两个动作中传播它。

代码语言:javascript
复制
def index
   @post = Post.all
end

def get
  @post = Post.where("author=?", params[:author_id])
end

如果你考虑一个RESTful应用程序接口,索引就更有意义了,索引意味着列出所有内容,然后获取(或显示)请求的接口并显示它!

票数 3
EN

Stack Overflow用户

发布于 2019-02-15 16:33:16

这个问题已经很老了,但它在2019年仍然在google中出现得很多,而且一些早期的答案已经被弃用,所以我想我应该分享一个可能的解决方案。

在模型中,引入一些作用域,并对传递的参数是否存在进行测试:

代码语言:javascript
复制
class Post
    scope :where_author_ids, ->(ids){ where(author_id: ids.split(‘,’)) if ids }
    scope :where_topic_ids,  ->(ids){ where(topic_id:  ids.split(‘,’)) if ids }

然后在控制器中,你可以想放多少过滤器就放多少,例如:

代码语言:javascript
复制
def list
    @posts = Post.where_author_ids(params[:author_ids])
                 .where_topic_ids(params[:topic_ids])                                  
                 .where_other_condition_ids(params[:other_condition_ids])
                 .order(:created_at)

然后,该参数可以是单个值或逗号分隔的值列表,这两种方法都可以正常工作。

如果参数不存在,它就会跳过where子句,不会根据特定条件进行过滤。如果参数存在,但它的值是空字符串,那么它将“过滤掉”所有内容。

当然,这种解决方案并不适用于所有情况。如果你有一个打开了多个过滤器的视图页面,但在第一次打开时,你想要显示所有数据,而不是没有数据,直到你按下“提交”按钮或类似的按钮(就像这个控制器一样),那么你就必须稍微调整一下。

我已经尝试过SQL注入,在我看来,rails在保证一切安全方面做得很好。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5820277

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档