【问题标题】:Rails3: how to set default conditions to has_manyRails3:如何将默认条件设置为 has_many
【发布时间】:2010-07-12 08:11:22
【问题描述】:

我有盒子和球。球在盒子里。球可以是红色和绿色。

class Box < ActiveRecord::Base
  has_many :balls
end

class Ball < ActiveRecord::Base
  belongs_to :box
  scope :green, where(:color => "green")
end

我只想用绿球设置 has_many。我知道finder_sql方法存在,但我不知道如何通过范围设置。

我希望以下示例是等效的:

@orders = @box.balls
@orders = @box.balls.green

【问题讨论】:

    标签: ruby-on-rails associations has-many finder-sql


    【解决方案1】:

    您可以随时使用:

    has_many :balls, :conditions => { :color => "green" }
    

    它在 Rails3 中有效,但我不确定是否会因为某些 ActiveRecord::Relation 等价物而弃用此语法。在与 Rails3 相关的官方文档中,这种语法仍然可用,所以我想这就像在 2.3.x 分支中一样。

    【讨论】:

    • 请注意,为了清楚起见,您可能希望调用关联 :green_balls。
    【解决方案2】:

    在 Rails 3 中,它略有变化:

    class Item
      scope :red, where(:colour => 'red')
      scope :since, lambda {|time| where("created_at > ?", time) }
    end
    
    red_items = Item.red
    available_red_items = red_items.where("quantity > ?", 0)
    old_red_items = Item.red.since(10.days.ago)
    

    Credit and more information

    【讨论】:

    • 我只想为 has_many 关联设置范围。我想@box.balls 返回所有绿色的球。我想 Ball.all 返回所有绿色和红色的球。
    • 确实如此。所以你在 Ball 模型上有 "scope :red, where(:coulour=>'red')" ... 然后,@box.balls.red
    • :) 我想避免手动使用范围。我想为 has_many 设置默认范围,可以吗?
    • 您需要在 /app/models/ball.rb 中设置范围 ------- 之后,您会说“Ball.red”以查找所有红球。你可以说“@box.balls.red”....如果你只想调用“@box.red_balls”,那么在 Box 上创建一个“red_balls”方法,让球 @box.balls.red”
    【解决方案3】:

    这是一个老问题,但我只是想做同样的事情,我在搜索时遇到了这个问题。我从未找到解决方案,但我想出了一些行之有效的方法。

    对于您的示例,您可以这样做:

    class Box < ActiveRecord::Base
      has_many :balls do
        def self.extended(base)
          base.where_values += Ball.green.where_values
        end
      end
    end
    
    class Ball < ActiveRecord::Base
      belongs_to :box
      scope :green, where(:color => "green")
    end
    

    我不知道这样做的含义,但经过一些初步测试后,它似乎可以正常工作。还有其他值可以设置,如eager_load_valuesjoin_valuesorder_values等。

    【讨论】:

      【解决方案4】:
      default_scope :color, :conditions => { :color => "green"}
      

      使用这个

      【讨论】:

      • default_scope 作用于整个模型。但我需要只对 has_many 关联起作用的选项。我想@box.balls 返回所有绿色的球。我想 Ball.all 返回所有绿色和红色的球。
      • 不要使用这个。每次用default_scope我都后悔了。请注意,有 lots of potential foot-guns 与此错误功能相关。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-28
      • 1970-01-01
      • 2013-12-06
      • 2021-03-03
      • 1970-01-01
      • 2010-09-08
      • 2020-08-26
      相关资源
      最近更新 更多