【问题标题】:Scoping with two foreign keys使用两个外键作用域
【发布时间】:2015-04-10 11:40:09
【问题描述】:

我有以下架构:

我希望为foreign_keys(author_ideditor_id)以及单独的keys(例如author_proposalseditor_proposals)选择调用proposals,我需要选择懒惰或急切地加载它们(例如User.includes(:proposals) 或不使用joins)。

更新:

#I have the scopes which is like this:
class User < ActiveRecord::Base
  has_many :author_proposals, class_name: 'Proposal', foreign_key: :author_id
  has_many :editor_proposals, class_name: 'Proposal', foreign_key: :editor_id
end

class Proposal < ActiveRecord::Base
  belongs_to :author, class_name: 'User', foreign_key: :author_id
  belongs_to :editor, class_name: 'User', foreign_key: :editor_id
end

但我需要一个通用的,它会给我所有的建议(author_proposalseditor_proposals),它也会急切地加载它们。我应该在has_many 上使用条件吗?

【问题讨论】:

  • 贴出你目前为此编写的代码
  • 我没有代码,这就是我要问的! :) 首选的方法是什么?它是否具有作用域并传递了一个 lambda?是用conditions吗?

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


【解决方案1】:

我会这样做:

class User < ActiveRecord::Base
  has_many :authored_proposals, class_name: 'Proposal', foreign_key: :author_id
  has_many :editored_proposals, class_name: 'Proposal', foreign_key: :editor_id

  def proposals
    Proposal.where('author_id = :id OR editor_id = :id', { id: id }).distinct
  end
end

class Proposal < ActiveRecord::Base
  belongs_to :author, class_name: 'User', foreign_key: :author_id
  belongs_to :editor, class_name: 'User', foreign_key: :editor_id

  def users
    User.where(id: [author_id, editor_id].uniq)
  end
end

【讨论】:

  • 这个是我一开始的想法,我想创建一个新方法但我需要eager_load它们。因此,例如,这个行不通: User.includes(:proposals).first 我觉得这不是 rails 的做法。
  • 为什么不只是User.includes(:authored_proposals, :editored_proposals)
  • 好主意,我可以添加以下内容:scope :proposals, -&gt;(user) { user.includes(:authored_proposals, :editored_proposals) } 但是当我调用User.proposals 时,它将始终是 eage_loaded。如果没有其他更多的 Rails 方法可以做到这一点,我会感到惊讶。
【解决方案2】:

你可以这样做:

class User < ActiveRecord::Base
  has_many :authored_proposals, class_name: 'Proposal', foreign_key: :author_id
  has_many :editored_proposals, class_name: 'Proposal', foreign_key: :editor_id

  def proposals
    authored_proposals | editored_proposals
  end
end

class Proposal < ActiveRecord::Base
  belongs_to :author, class_name: 'User', foreign_key: :author_id
  belongs_to :editor, class_name: 'User', foreign_key: :editor_id

  def users
    author | editor
  end
end

您可以通过以下方式预先加载proposalsUser.includes(:authored_proposals, :editored_proposals)。这不是纯粹的 Rails 方式,但对我来说似乎更干净。



你也可以这样做:

class User < ActiveRecord::Base
  has_many :authored_proposals, class_name: 'Proposal', foreign_key: :author_id
  has_many :editored_proposals, class_name: 'Proposal', foreign_key: :editor_id

  has_many : proposals, finder_sql: proc { "SELECT * FROM proposals WHERE (proposals.author_id = #{id} or proposals. editor_id = #{id})" }
end

【讨论】:

    【解决方案3】:

    这样设置你的关联:

    class User < ActiveRecord::Base
      has_many :author_proposals, :class_name => "Proposal", :foreign_key => "author_id"
      has_many :editor_proposals, :class_name => "Proposal", :foreign_key => "editor_id"
    end
    
    class Proposal < ActiveRecord::Base
      belongs_to :author, :class_name => 'User', :foreign_key => "author_id"
      belongs_to :editor, :class_name => 'User', :foreign_key => "editor_id"
    end
    

    【讨论】:

    • 谢谢。这是简单的author_proposalseditor_proposals,但我需要它会找到所有提案的提案。
    猜你喜欢
    • 2021-12-01
    • 1970-01-01
    • 2014-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    • 1970-01-01
    相关资源
    最近更新 更多