Rails умножает объединенные столбцы на нуль внешнего ключа

#ruby-on-rails

#ruby-on-rails

Вопрос:

У меня есть эти таблицы:

 STOCKDIARY

- ID, DATE, PRODUCT, UNITS, PRICE

PRODUCTS

- ID, NAME, CONSIGNOR

CONSIGNORS

- ID, NAME, COMMISSION
  

Я настроил все ассоциации. Так что, если, на мой взгляд, я использую:

 stockdiary.product.consignor.try(:COMMISSION)
  

Я получаю правильную комиссию за каждый продукт в строке stockdiary.

Обратите внимание, что я использую try , потому что не у всех продуктов есть отправитель.

Но теперь мне нужно показать stockdiary.PRICE * stockdiary.product.consignor.COMMISSION

Итак, в модели Stockdiary я установил

 def total_commission
  (self.PRICE * self.product.consignor.COMMISSION)
end
  

Но это выдает мне ошибку:
undefined method 'COMMISSION' for nil:NilClass

Я думаю, проблема возникает из-за того, что некоторый продукт имеет пустое значение в столбце ОТПРАВИТЕЛЬ. Просто чтобы убедиться, что я ввел значение для каждой строки в столбце КОМИССИЯ ОТПРАВИТЕЛЕЙ таблицы. Но ошибка все еще присутствует.

Я бы хотел, чтобы строка stockdiaries с продуктами без отправителя отображала 0 в качестве комиссии.

Как исправить?

Ответ №1:

Метод1:

Укажите столбец try для consignor вместо COMMISSION или укажите для обоих.

 def total_commission
    (self.PRICE * self.try(:product).try(:consignor).try(:COMMISSION))
end
  

Метод2:

Также вы можете использовать,

 def total_commission
    consignor = self.product.consignor.present? ?  self.product.consignor.COMMISSION : 0
    (self.PRICE * consignor)
end
  

что он делает, так это то, что если есть отправитель, он принимает его, иначе он принимает 0, как вы упомянули.

Комментарии:

1. @catmal, попробуйте второй подход, он больше подходит для rails

2. Второй подход возвращает ожидаемое местоположение (#69853755169400), получено значение Fixnum (#47292841845800)

3. Я проголосовал за это. Но, честно говоря, у меня нет знаний, чтобы судить, какой из 3 подходов лучше.. Итак, я принял первый..

Ответ №2:

Как вы сказали ранее:

Обратите внимание, что я использую try , потому что не у всех продуктов есть отправитель.

Итак, вам нужно:

 def total_commission
  commission = self.productamp;.consignoramp;.COMMISSION
  if self.PRICE amp;amp; commission
     (self.PRICE * commission)
  else
      nil
  end
end
  

Ответ №3:

 def total_commission
  commission = product.consignor.try(:COMMISSION)
  commission ? (PRICE * commission) : 0
end
  

Комментарии:

1. Спасибо! Я попробую другие решения, хотя

2. Я не думаю, что вам нужно использовать self , если вы просто читаете атрибут

3. Если я использую ваше решение как есть, оно возвращает неинициализированную константу Stockdiary::PRICE