Подтвердить что ты не робот

Rails has_many с динамическими условиями

Я хочу создать модель, которая соединяется с другим с помощью ассоциации 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 {}'))

Возможно ли это?

4b9b3361

Ответ 1

Rails 4+ way (Спасибо Томасу, который ответил на это ниже):

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}" }

Рельсы 3 и ниже:

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

Нет. Это не ошибка. Условия указаны в одинарных кавычках и содержат код #{self.regra_fiscal}. Когда условие условия будет эвакуировано, метод regra_fiscal будет вызван на объект self (независимо от класса). Ввод двойных кавычек не будет работать.

Надеюсь, это то, что вы ищете.

Ответ 2

Рельсы 4 + путь:

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

Ответ 3

Существует другое решение. Однако это не будет область по умолчанию.

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)

Я не уверен, что это элегантно и что-то, что решит вашу проблему. Там могут быть лучшие способы сделать это.

Ответ 4

Rails 4 + другой способ:

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

Ответ 5

В Rails 3.1 необходимо использовать proc, Proc.new { "field = # {self.send(: other_field)}" }

Ответ 6

В 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, что и родительский.