加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 使用`tap`构建Rails范围

发布时间:2020-12-17 03:48:42 所属栏目:百科 来源:网络整理
导读:我的方法看起来像 class Student ActiveRecord::Base def self.search(options = {}) all.tap do |s| s.where(first_name: options[:query]) if options[:query] s.where(graduated: options[:graduated]) if options[:graduated] # etc there are many more
我的方法看起来像

class Student < ActiveRecord::Base
  def self.search(options = {})
    all.tap do |s|          
      s.where(first_name: options[:query])     if options[:query]
      s.where(graduated:  options[:graduated]) if options[:graduated]

      # etc there are many more things that can be filtered on...
    end
  end
end

在调用此方法时,我正在收回所有结果,而不是我期望的过滤集.好像我的点击功能没有像我期望的那样工作.执行此操作的正确方法是什么(不将所有内容分配给变量.如果可能,我想在此处使用块).

解决方法

点击不适用于此.

> all是一个ActiveRecord :: Relation,一个等待发生的查询.
> all.where(…)返回一个新的ActiveRecord :: Relation新查询.
>但是,检查documentation是否为tap,您会看到它返回调用它的对象(在本例中为all),而不是块的返回值.

即它的定义如下:

def tap
  yield self # return from block **discarded**
  self
end

当你想要的只是:

def apply
  yield self # return from block **returned**
end

或类似的东西.

这就是您继续获取所有返回对象的原因,而不是查询产生的对象.我的建议是你建立你发送到哪里的哈希,而不是链接到哪里调用.像这样:

query = {}
query[:first_name] = options[:query]     if options[:query]
query[:graduated]  = options[:graduated] if options[:graduated]
# ... etc.

all.where(query)

或者可能更好的实现:

all.where({
  first_name: options[:query],graduated:  options[:graduated],}.delete_if { |_,v| v.empty? })

(如果中间变量不符合您的口味.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读