【问题标题】:Rails search with OR in ActiveRecord::RelationRails 在 ActiveRecord::Relation 中使用 OR 进行搜索
【发布时间】:2011-10-03 22:41:05
【问题描述】:

经过很长时间的搜索,我终于问了这个问题: 如何在 Rails 3.0 中使用 ActiveRecord::Relation 进行 OR 条件查询?基本上我相信它必须与范围界定和东西做一些事情......

这是我所拥有的:

class Practice < ActiveRecord::Base
  attr_accessible :name

  has_and_belongs_to_many :doctors
  has_and_belongs_to_many :services
end

class Doctor < ActiveRecord::Base
  attr_accessible :first_name, :last_name

  has_and_belongs_to_many :practices
  has_and_belongs_to_many :services
end

class Service < ActiveRecord::Base
  attr_accessible :name, :about

  has_and_belongs_to_many :practices
  has_and_belongs_to_many :doctors
end

我想要实现的是一个表单,我可以在其中进行搜索查询并返回 ActiveRecord::Relation 对象(因此我可以将它与 will_paginate 等一起使用)和实践列表。查询应该找到@practice.name 匹配query_string 或@practice.doctors.first_names 匹配query_string 或@practice.doctors.last_names 匹配query_string 或@practice.services.names 匹配query_string 的任何实践。换句话说 - 假设 query_string 匹配服务的名称,我想获取与该服务相关的实践列表。或者,如果 Doctor 的 first_name 或 last_name 与 query_string 匹配,那么我会得到与该 Doctor/Doctors 关联的实践。当然,Practice.name 也是不错的老对手:D

我意识到我的 has_and_belongs_to_many 关联在这里并不好,这只是为了演示目的,但我很高兴听到有人可以为我的案例提供迁移和关联方面的帮助。

谢谢。

附:正如我所说,我使用 Rails 3.0,我相信它必须对范围做一些事情(但我当然可能是错的)。我也尝试过 MetaWhere 但无法使其工作.... :(

【问题讨论】:

  • 我听说你说你想在一个数据库查询中做到这一点吗? =P
  • 是的,原因是 - 我可以做这样的事情并让我们说 3 ActiveRecord::Relation 对象,但是当我尝试将它们放在一起时,它们变成了一个数组。正如我所说,我真的需要它是 ActiveRecord::Relation,这样我就可以将它与分页和其他东西一起使用。附言没有找到从数组中创建 ActiveRecord::Relation 对象的方法。
  • 是的Relations 不像数据库视图那样工作,数组就是数组,它就在你脸上的 RAM 中。在下面查看我的答案,希望它有效,或者至少给你一个新的想法!
  • Squeel 是 MetaWhere 的更新形式,应该用于 Rails 3.0

标签: sql ruby-on-rails ruby ruby-on-rails-3 activerecord


【解决方案1】:

让我们看看结果如何:

class Practice < ActiveRecord::Base
  class < self
    def by_any_name(param)
      joins(:doctors, :services).
      where(<<-SQL, :name => param)
             doctors.first_name = :name OR
             doctors.last_name  = :name OR
             practices.name     = :name OR
             services.name      = :name
      SQL
    end
  end
end

去年的范围如此

还有一些左加入 fer ya(需要测试!):

joins('LEFT JOIN
         (doctors_practices INNER JOIN doctors
            ON doctors.id = doctors_practices.doctors_id)
          ON doctors_practices.practice_id = practices.id
       LEFT JOIN
         (practices_services INNER JOIN services
            ON services.id = practices_services.service_id)
          ON practices_services.practice_id = practices.id')

天哪,我的就寝时间已经过去了。

【讨论】:

  • 如果我在没有任何相关医生或服务的情况下进行实践,这会给予任何回报吗?谢谢。
  • 不,只有使用这种语法的内连接。你需要左连接还是什么?
  • 是的,我想我需要像左关节这样的东西,因为即使我在 Services 或 Doctors 中找不到任何匹配项,我仍然想从 Practices 中获得匹配的东西。或者,如果我在所有桌子上都有匹配,那么我需要所有 :D 所以感觉我的大练习桌在左边,另外两个在右边。
  • 感谢您的帮助,但我得到 SQLite3::SQLException: no such column: doctors_practices.practice_id: SELECT "practices".* FROM "practices" LEFT JOIN (ActiveRecord::StatementInvalid) 错误联合的。此外,我认为我无法通过此查询避免重复结果,我需要对我的迁移做些什么吗?
  • 您可以从 has_and_belongs_to_many 连接表的迁移中读取列名。
【解决方案2】:

您可以深入了解 ARel 或者——看看我在那里做了什么:)—— 看看非常方便的 gem squeel,它可以让你用漂亮的语法做你想做的事。

https://github.com/ernie/squeel

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 2017-11-01
    • 1970-01-01
    相关资源
    最近更新 更多