Rails has_many с динамическими условиями - PullRequest
54 голосов
/ 17 марта 2010

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

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

Ответы [ 6 ]

92 голосов
/ 17 марта 2010

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

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

Rails 3.1+ way:

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}.Когда условие условий оценивается, метод regra_fiscal будет вызываться для объекта self (каким бы ни был класс).Положить двойные кавычки не получится.

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

55 голосов
/ 06 декабря 2013

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

has_many :faixas_aliquotas, -> (object){ where("regra_fiscal = ?", object.regra_fiscal)},  :class_name => 'Fiscal::FaixaAliquota'
8 голосов
/ 17 марта 2010

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

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 голосов
/ 10 августа 2014

Рельсы 4 + другим способом:

has_many :faixas_aliquotas, -> (object){ where(regra_fiscal: object.regra_fiscal) }, :class_name => 'Fiscal::FaixaAliquota'
3 голосов
/ 01 декабря 2011

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

1 голос
/ 22 июня 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...