Rails具有动态条件

时间:2010-03-17 12:38:06

标签: ruby-on-rails model

我想要的是创建一个以动态方式使用has_many关联与另一个连接的模型,而不使用这样的外键:

has_many :faixas_aliquotas, :class_name => 'Fiscal::FaixaAliquota',
            :conditions => ["regra_fiscal = ?", ( lambda { return self.regra_fiscal } ) ]

但我收到错误:

: SELECT * FROM "fis_faixa_aliquota" WHERE ("fis_faixa_aliquota".situacao_fiscal_id = 1
AND (regra_fiscal = E'--- !ruby/object:Proc {}'))

这可能吗?

6 个答案:

答案 0 :(得分:92)

Rails 4+方式(感谢Thomas在下面回答此问题):

has_many :faixas_aliquotas, -> (object) { 
           where("regra_fiscal = ?", object.regra_fiscal)
         },
         :class_name => 'Fiscal::FaixaAliquota'

Rails 3.1+方式:

has_many :faixas_aliquotas, :class_name => 'Fiscal::FaixaAliquota',
         :conditions => proc { "regra_fiscal = #{self.regra_fiscal}" }

Rails 3及以下:

has_many :faixas_aliquotas, :class_name => 'Fiscal::FaixaAliquota',
         :conditions => ['regra_fiscal = #{self.regra_fiscal}']

没有。这不是一个错误。条件以单引号指定,但仍包含代码#{self.regra_fiscal}。当条件子句被评估时,将在self的对象上调用regra_fiscal方法(无论类是什么)。放双引号是行不通的。

我希望这就是你要找的东西。

答案 1 :(得分:55)

Rails 4 +方式:

has_many :faixas_aliquotas, -> (object){ where("regra_fiscal = ?", object.regra_fiscal)},  :class_name => 'Fiscal::FaixaAliquota'

答案 2 :(得分:8)

还有另一种解决方案。但是,这不是默认范围。

has_many :faixas_aliquotas, :class_name => 'Fiscal::FaixaAliquota' do 
  def filter(situacao_fiscal)
    find(:all, :conditions => {:regra_fiscal => situacao_fiscal.regra_fiscal})
  end
end

这样你就能做到

situacao_fiscal.faixas_aliquotas.filter(situacao_fiscal)

我不确定这是否优雅,可以解决您的问题。可能有更好的方法来做到这一点。

答案 3 :(得分:4)

Rails 4 + 另一种方式:

has_many :faixas_aliquotas, -> (object){ where(regra_fiscal: object.regra_fiscal) }, :class_name => 'Fiscal::FaixaAliquota'

答案 4 :(得分:3)

在Rails 3.1中需要使用proc,Proc.new {“field =#{self.send(:other_field)}”}

答案 5 :(得分:1)

在Rails 3.1中,您可以根据您的条件使用Proc.new。如@Amala所述,但是生成这样的哈希:

has_many :faixas_aliquotas, :class_name => 'Fiscal::FaixaAliquota',
   :conditions => {:regra_fiscal => Proc.new { {:regra_fiscal => self.regra_fiscal} }

这种方法的好处是,如果你执行object.faixas_aliquotas.build,新创建的对象将自动具有与父级相同的regra_fiscal属性。