Как перехватить acceptpts_nested_attributes_for? - PullRequest
4 голосов
/ 13 сентября 2011

У меня есть приложение Rails с двумя моделями: SalesTransactions и PurchaseOrders.

В модели PurchaseOrders новые записи регистрируются с использованием поля purchase_order_number в качестве ключевого поля.Я использую метод создания модели, чтобы найти, был ли ранее зарегистрирован этот «purchase_order_number», и, если это так, повторно использовать эту запись и использовать ее идентификатор в записи SalesTransaction.Если это имя еще не было зарегистрировано, я продолжаю создавать, а затем использую новый идентификатор записи PurchaseOrder в SalesTransaction (Foreign_id, ссылающийся на связанный заказ).

Обратите внимание, что я неиметь существующий идентификатор записи PurchaseOrder до тех пор, пока я не выполню поиск в методе создания (так что это не вопрос «как обновить запись, используя« accepts_nested_attributes_for »?», я могу это сделать, когда у меня будет идентификатор).

В некоторых ситуациях мое приложение записывает новую SalesTransaction и одновременно создает новый PurchaseOrder.Он использует accepts_nested_attributes_for для создания записи PurchaseOrder.

Проблема заключается в том, что при использовании 'accepts_nested_attributes_for' create не вызывается, и поэтому моя модель не имеет возможности перехватить create и искать, если'purchase_order_number' уже зарегистрирован и обрабатывает этот случай.

Буду признателен за предложения о том, как перехватить создания 'accepts_nested_attributes_for', чтобы разрешить некоторую предварительную обработку (т. е. посмотреть, если запись PurchaseOrder с этим номеромуже существует, и если это так, используйте его.)

Не у всех Sales есть параметр PurchaseOrder, поэтому запись PurchaseOrder является необязательной в рамках SalesTransaction.

(я видел kludge, включающий: reject_if, но это не позволяет мне добавить существующий идентификатор записи в качестве Foreign_id в родительской записи.)

Спасибо.

Ответы [ 4 ]

1 голос
/ 23 сентября 2011

Вы можете использовать обратные вызовы validate и save, чтобы делать то, что вам нужно.

При условии установки:

class SalesTransaction < ActiveRecord::Base
  belongs_to :purchase_order, :foreign_key => "po_purchase_order_no", 
    :primary_key => "purchase_order_no"

  accepts_nested_attributes_for :purchase_order
end

class PurchaseOrder < ActiveRecord::Base
  has_many :sales_transactions, :foreign_key => "po_purchase_order_no", 
    :primary_key => "purchase_order_no"

  before_validation :check_for_exisitng_po # maybe only on create?

  accepts_nested_attributes_for :sales_transactions

  private

  def check_for_exisitng_po
    existing_po = PurchaseOrder.find_by_purchase_order_no(self.purchase_order_no)

    if existing_po
      self.id = existing_po.id
      self.reload # don't like this, also will overwrite incoming attrs
      @new_record = false # tell AR this is not a new record
    end

    true
  end
end

Это должно снова полностью использовать accepts_nested_attributes_for.


Гист с тестами

0 голосов
/ 20 сентября 2011

Я собирался написать функцию before_save, но вы говорите так:

Он использует accepts_nested_attributes_for для создания записи PurchaseOrder.

Итак, в SalesTransactionпроцесс потока, зачем вообще его искать?Вы должны просто получить следующий доступный ... не должно быть причины искать то, чего не было до СЕЙЧАС.

0 голосов
/ 23 сентября 2011

Хорошо, я оставил этот вопрос на некоторое время и предложил вознаграждение, но у меня нет ответа, который я ищу (хотя я, конечно, ценю людей, пытающихся помочь).

Я пришел к выводу, что я не упустил какой-то трюк, и на момент написания статьи не было аккуратного решения, только обходные пути.

Таким образом, я собираюсь переписать свое приложение, чтобы избежать использования accept_nested_attributes_for, и публиковать записи SalesTransaction и PurchaseOrder отдельно, поэтому код создания можно применять в обоих случаях.

Позор, как accept_nested ... в остальном довольно круто, но в данном случае это недостаточно полно.

Я до сих пор люблю Rails; -)

0 голосов
/ 20 сентября 2011

Две идеи: Вы смотрели на обратные вызовы ассоциации?Возможно, вы можете «перехватить» acceptpts_nested_attributes_for на этом уровне, используя: before_add, чтобы проверить, находится ли он уже в БД перед созданием новой записи.

Другая идея заключается в постобработке.В after_save / update вы можете просмотреть все записи с именем (оно должно быть уникальным), а если их несколько, объединить их.

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