Rails хранит разные таблицы в одном контроллере - PullRequest
0 голосов
/ 18 марта 2019

У меня есть две модели, Домашний скот и История

У скота много историй, а история принадлежит скоту

Это метод создания внутри LivestockController

  # POST /livestocks
  # POST /livestocks.json
  def create
    @livestock = Livestock.new(livestock_params.permit!)

    respond_to do |format|
      if @livestock.save
          format.html { redirect_to @livestock }
          flash[:success] = "Livestock was successfully created"
          format.json { render :show, status: :created, location: @livestock }
      else
        format.html { render :new }
        format.json { render json: @livestock.errors, status: :unprocessable_entity }
      end
    end
  end

Я хотел создать запись в таблице историй с

history = History.new(livestock_id: @livestock.id, event: "Purchased", event_date: @livestock.purchase_date, image: @livestock.image)
history.save!

внутри метода создания

Как я могу это сделать? Я не могу поместить это в метод создания, потому что он говорит Validation failed: Livestock must exist по-видимому, @livestock еще не имеет атрибута id

Edit: это все еще вызывает то же исключение, когда я ставлю его после if @livestock.save

Однако я нашел обходной путь, используя переменную сеанса. Поскольку он перенаправлен на страницу показа, я создал следующее в методе создания

session[:created] = "created"

И в моем методе показа

  # GET /livestocks/1
  # GET /livestocks/1.json
  def show
    if session[:created] == "created"
      history = History.new(livestock_id: params[:id], event: "Purchased", event_date: @livestock.purchase_date, image: @livestock.image)
      history.save!
      session.delete(:created)
    end
  end

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

1 Ответ

0 голосов
/ 18 марта 2019

Запись скота создается при вызове save (и нет ошибки проверки). Таким образом, один из вариантов - создать историю внутри этого if условия:

if @livestock.save

Другой вариант - использовать обратный вызов after_create в модели livestock, который создаст объект history сразу после создания livestock. Вы должны быть осторожны, потому что обратный вызов может вызываться, когда он вам не нужен (т.е. при импорте данных).

Последний вариант - создать отдельный объект службы, который создаст livestock и все другие необходимые объекты. Это, вероятно, лучший подход, но он потребует больше настраиваемого кода.

Обновление

Пожалуйста, не забудьте переместить блок if / else за пределы блока respond_to:

if @livestock.save
  # create history object here

  respond_to do |format|
    format.html { redirect_to @livestock }
    flash[:success] = "Livestock was successfully created"
    format.json { render :show, status: :created, location: @livestock}
  end
else
  respond_to do |format|
    format.html { render :new }
    format.json { render json: @livestock.errors, status: :unprocessable_entity }
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...