【问题标题】:How can I retrieve records with an optional join?如何使用可选连接检索记录?
【发布时间】:2012-04-23 16:51:50
【问题描述】:

我希望为用户检索一组时间记录。查询应返回范围为公共(即私有 == false)或私有(即私有 == true)的网络的记录,并且用户具有该时间的 Slot 记录。

我想用 ActiveRecord 来做这件事,但我发现的唯一方法是做两个单独的查询。这很好,除了结果是数组而不是 ActiveRecord 关系防止链接等。

有什么建议吗?

class TimeAccessPolicy
  attr_reader :network

  def initialize(network)
    @network = network
  end

  def accessible_times_for(user)
    return [] unless user.is_member_of?(network)
    times = network.times.where(private: false)
    times + network.times.joins(:slots).where(private: true, slots: {user_id: user.id})
  end
end

-- 编辑:

class Time < ActiveRecord::Base
  belongs_to :network
  has_many   :slots
  has_many   :participants, through: :slots, source: :user

  # has private boolean
  ...
end

class Network < ActiveRecord::Base
  has_many   :memberships, as: :memberable, dependent: :destroy
  has_many   :users, through: :memberships
  has_many   :times

  ...
end

class Slot < ActiveRecord::Base
  belongs_to :user
  belongs_to :time

  ...
end

【问题讨论】:

  • 您能否发布更多上下文,我想您想为您的模型添加一些范围。贴出Network model,说明times从何而来,是不是Network Model中的has_many关系?每当我听到“保留 ActiveRecord 关系”时,我都会立即想到范围。

标签: ruby-on-rails activerecord join


【解决方案1】:

您可以使用scoped method

像这样:

times = network.times.scoped
# times is still ActiveRecord relation
if private
  times = times.joins(:slots).where(private: true, slots: {user_id: user.id})
else
  times = times.where(private: false)
end

这段代码只做一次查询

【讨论】:

    猜你喜欢
    • 2011-09-29
    • 1970-01-01
    • 2018-04-24
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 2012-08-20
    • 1970-01-01
    • 2021-10-27
    相关资源
    最近更新 更多