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 {}'))
Возможно ли это?
Ответы
Ответ 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
, что и родительский.