【问题标题】:Is possible to rewrite this query using only named scopes?是否可以仅使用命名范围重写此查询?
【发布时间】:2015-01-12 21:07:26
【问题描述】:

我希望仅使用命名范围来编写此查询。原因很简单,当我改变Client 被视为活动的方式时,我不想到处更改代码(User 被视为可连接也是如此)

这是我的代码

client.rb

class Client < ActiveRecord::Base
  has_one :user

  scope :actives, -> { where(starting_date: a_date, finishing_date: another_date, enabled: true) }
end

user.rb

class User < ActiveRecord::Base
  belongs_to :client

  scope :connectable, -> { where.not(access_token: nil, instance_url: nil) }
end

您可以在这里找到我编写此查询的尝试:

# What I would like to write
User.eager_load(:client).connectable.where("client is in :actives scope")

# Current options
# 1 - (but this violates dry)
User.eager_load(:client).connectable.where(['clients.starting_date = ? AND clients.finishing_date = ? AND clients.enabled = ?', a_date, another_date, true).references(:client)

# 2 - My best attempt so far
User.connectable.where(client_id: Client.actives.pluck(:id))

以及指向GIST 的链接以供参考

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4.1


    【解决方案1】:

    您正在寻找的是 ARel 的 merge 方法。 (An article on this here.)

    试试这个:

    User.connectable.includes(:client).merge(Client.actives).references(:clients)
    

    includes(:client) 将引入来自用户的 :client 关系,这将使.merge(Client...) 范围工作。 Rails 4+ 要求 .references 明确声明 includes 语句将引用哪个表。

    【讨论】:

    • 很好,我正在尝试使用 merge,但没有考虑到我必须使用包含(或 rails 4 中的 eager_load)和新的 references 东西。谢谢,我会用这个更新我的代码。
    【解决方案2】:

    我不确定这是一个多么好的想法,但只要您确保列名的名称间距正确(即,如果不给表名添加前缀,就不能在 Client 和 User 中都使用 'foo' ) 那么这应该可以工作:

    User.eager_load(:client).connectable.where(Client.active.where_values.map(&:to_sql).join(" AND "))

    一定有更好的方法,但以上方法对我有用:

    课程模式:

    scope :valid, -> { enabled.has_country }
    scope :has_country, -> { where.not(country_id:nil) }
    

    Rails 控制台:

    > Course.where(Course.valid.where_values.map(&:to_sql).join(" AND ")).to_sql
    => "SELECT \"courses\".* FROM \"courses\"  
        WHERE (\"courses\".\"is_enabled\" = 't' 
        AND \"courses\".\"country_id\" IS NOT NULL)"
    

    【讨论】:

    • 嗯,这对我来说太老套了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-31
    • 2013-12-25
    • 1970-01-01
    相关资源
    最近更新 更多