Rails создает и обновляет 2 записи модели одновременно - PullRequest
2 голосов
/ 20 марта 2010

У меня есть 2 таблицы продукта и истории

таблица продуктов:

id   name     type            price     location
1    abc      electronics     $200      aisle1

таблица истории:

id   product_id    status
1    1             price changed from $200 to $180

Каждый раз, когда пользователь обновляет цену или местоположение продукта, нажимая кнопку обновления, изменения должны автоматически отражаться в столбце статуса истории, при этом пользователю не нужно вводить это вручную.

Если цена обновляется с 200 до 180, то будет создана новая строка истории с новым идентификатором, а в столбце состояния будет указано «цена изменена с 200 до 180 долларов».

Если местоположение обновляется с прохода 1 до прохода 2, отображается состояние «loc изменился с прохода 1 на проход 2».

Я пытался:

@product = Product.new(params[:product])
@history = History.new(params[:history])
if @product.save
  @history.new(attributes)  # I am not sure of whether this approach is correct

Буду очень признателен, если кто-нибудь подскажет, как в этом случае можно автоматически обновлять историю.

Ответы [ 3 ]

3 голосов
/ 20 марта 2010

Добавьте фильтр after_save к модели продукта.

class Product < ActiveRecord::Base
  after_save :make_history
  has_many  :histories

  def make_history
    status = ""
    status << "Price changed from #{price_was} to #{price}" if price_changed?
    status << "Location changed from #{location_was} to #{location}" if location_changed?
    return if status.empty?        
    errors = histories.create(:status = status).errors.full_messages.join(",\n") 
    # return true if no error
    return true if errors.empty?

    # Roll the error to base
    errors.add_to_base("History creation error:\n#{errors}")

    # explicitly rollback
    raise ActiveRecord::Rollback

    # return false to terminate the callback chain
    return false
  end
end

Редактировать

Я добавил код для отката Product, когда Historyсоздание не удалось.

3 голосов
/ 20 марта 2010

Вы хотите использовать Observer .

Вы можете настроить его так:

class ProductObserver < ActiveRecord::Observer
  def after_save(product)
    #get attributes here
    history.new(attributes)
    history.save
  end
end

Обратите внимание, что вы должны вручную указать, какие наблюдатели загружаются в вашей конфигурации среды; Вы не можете просто добавить файл и заставить его работать.

0 голосов
/ 20 марта 2010

Один из способов - использовать обратный вызов after_save для модели. Добавьте это к вашей модели продукта ActiveRecord:

after_save :update_history

def update_history
   do_whatever
end

проверить здесь .

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