web-dev-qa-db-ja.com

Rails has_many with dynamic conditions

私が欲しいのは、次のような外部キーなしで、動的な方法で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 {}'))

これは可能ですか?

56
Fabiano Soriani

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メソッドが呼び出されます。二重引用符を使用しても機能しません。

これがあなたが探しているものであることを願っています。

95
Chirantan

レール4 +方法:

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

別の種類の解決策があります。ただし、これはデフォルトのスコープではありません。

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)

これがエレガントで、あなたの問題を解決するものかどうかはわかりません。これを行うより良い方法があるかもしれません。

8
Chirantan

Rails 4 +別の方法:

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

In Rails 3.1 procを使用する必要がある、Proc.new {"field =#{self.send(:other_field)}"}

3
Amala

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属性を親として。

1
bayfieldcoder