Rails具有动态条件

Fab*_*ani 57 model ruby-on-rails

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

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

但我得到错误:

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

这可能吗?

Chi*_*tan 96

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

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

Rails 3.1+方式:

has_many :faixas_aliquotas, :class_name => 'Fiscal::FaixaAliquota',
         :conditions => proc { "regra_fiscal = #{self.regra_fiscal}" }
Run Code Online (Sandbox Code Playgroud)

Rails 3及以下:

has_many :faixas_aliquotas, :class_name => 'Fiscal::FaixaAliquota',
         :conditions => ['regra_fiscal = #{self.regra_fiscal}']
Run Code Online (Sandbox Code Playgroud)

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

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

  • 更好的方法是使用绑定变量来避免SQL注入,即`proc {["regra_fiscal =?",regra_fiscal]}` (6认同)
  • Rails 4掉了这个. (3认同)

Tho*_*mas 56

Rails 4 +方式:

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

  • 对我来说工作得很好!(我不知道我在做什么) (6认同)

Chi*_*tan 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
Run Code Online (Sandbox Code Playgroud)

这样你就可以做到

situacao_fiscal.faixas_aliquotas.filter(situacao_fiscal)
Run Code Online (Sandbox Code Playgroud)

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


Geo*_*vet 5

Rails 4+ 的另一种方式:

has_many :faixas_aliquotas, -> (object){ where(regra_fiscal: object.regra_fiscal) }, :class_name => 'Fiscal::FaixaAliquota'
Run Code Online (Sandbox Code Playgroud)