【问题标题】:Rails Scoped has many through has many with scopeRails Scoped 有很多 through 有很多 with 范围
【发布时间】:2021-04-08 14:34:39
【问题描述】:

我有一个带有作用域的模型有很多。我想将 a has many 链接到那个:


 class X < ApplicationRecord
  has_many :ys, {foreign_key: :y_id} do
    def for_z(z)
      where("boolean_flag = #{z.boolean_flag}")  
    end

  has_many :bs, through: :ys # but I want to get only the bs for ys.for_z(z)
  end

这里的y 属于b

所以最后我想打电话:

something.xs.ys.for(z).bs

现在我还能做

something.xs.ys.for(z).map {|y| y.b}

但我想正确连接关联

【问题讨论】:

    标签: ruby-on-rails activerecord ruby-on-rails-5 has-many-through has-many


    【解决方案1】:

    您实际上需要定义第二个关联:

    class Project < ApplicationRecord
      has_many :issues
      has_many :open_issues,
        -> { where(status: 'open') },
        class_name: 'Issue'
        
      has_many :assignees, through: :open_issues
    end
    

    has_many through: 关联仅采用它加入的另一个关联的名称。您不能定义通过 association extension 的关联,您错误地将其称为范围。

    作用域实际上只是一个类方法,可以在任何关系上调用(因为它代理类),而关联扩展只能在 association proxies 上调用。

    如果您想实际创建a scoped association,则需要传递一个可调用对象,例如 lambda。

    has_many :open_issues,
      -> { where(status: 'open') },
      class_name: 'Issue'
    

    这实际上只是将一组过滤器直接应用于关联本身。

    something.xs.ys.for(z).bs
    

    实际上与 Rails 中关联的实际工作方式不兼容。关联不能在关系或关联代理对象上调用 - 只能在记录本身上调用。

    【讨论】:

    • 哇,我被追星了!尽管文档中有多个实例表明我可以,但我无法弄清楚如何将参数传递给作用域关联,在这种情况下,我的 for_z 作用域需要传递一个参数。因此,我只能使用接受参数的def for_z 策略。您是否认为我应该能够将 arg 传递给我的作用域关联?
    • 不,您不能将参数传递给 lambda,因为当您使用包含、连接和 eager_load 时,它们无法传递该参数。
    猜你喜欢
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 2016-03-08
    • 1970-01-01
    • 2017-04-25
    • 1970-01-01
    相关资源
    最近更新 更多