Ruby-on-rails Rails has_many 具有动态条件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2462203/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:24:43  来源:igfitidea点击:

Rails has_many with dynamic conditions

ruby-on-railsmodel

提问by Fabiano Soriani

What I want is to create a Model that connects with another using a has_many association in a dynamic way, without the foreign key like this:

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

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

But I get the error:

但我收到错误:

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

Is this possible?

这可能吗?

回答by Chirantan

Rails 4+ way (Thanks to Thomas who answered this below):

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

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

Rails 3.1+ way:

Rails 3.1+ 方式:

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

Rails 3 and below:

Rails 3 及以下:

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

No. This is not a mistake. The conditions are specified in single quotes and still contains the code #{self.regra_fiscal}. When the conditions clause is evaulated, the regra_fiscal method will be called on the object of self(whatever the class is). Putting double quotes will not work.

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

I hope this is what you are looking for.

我希望这就是你正在寻找的。

回答by Thomas

Rails 4+ way:

Rails 4+ 方式:

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

回答by Chirantan

There is another kind of solution. However, this wont be the default scope.

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

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

This way you would be able to do

这样你就可以做到

situacao_fiscal.faixas_aliquotas.filter(situacao_fiscal)

I am not sure if this is elegant and something that would solve your problem. There may be better ways of doing this.

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

回答by GeoffreyHervet

Rails 4+another way:

Rails 4+ 的另一种方式:

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

回答by Amala

In Rails 3.1 need to use proc, Proc.new { "field = #{self.send(:other_field)}" }

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

回答by bayfieldcoder

In Rails 3.1 you can use Proc.new for your conditions. as stated by @Amala, but instead generate a hash like this:

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

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

The benefit of this approach is that if you do object.faixas_aliquotas.build, the newly created object will automatically have the same regra_fiscalattribute as the parent.

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