Уничтожить запись вместо обновления в форме вложенной модели - PullRequest
0 голосов
/ 19 февраля 2019

У меня есть модель opening_times, которая записывает время работы магазинов.

create_table "opening_times", force: :cascade do |t|
    t.string "day"
    t.time "morning"
    t.time "evening"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.bigint "shop_id"
    t.index ["shop_id"]
  end

Эта модель обновляется только через вложенную форму в действии edit контроллера shops.У меня нет opening_times контроллера.

Тогда в основном то, что я могу сделать, довольно сильно ограничено: действие update.

Хотя у меня есть проблема: когда раньше было время открытия для определенного дня, скажем, вторник, и пользователь хочет, чтобы этот день не работал, пользователь делает оба поля morning и evening blanks.

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

тогда в файле модели я установил это:

before_save :delete_records_with_missing_hours

private 

def delete_records_with_missing_hours
    if self.morning.blank? or self.evening.blank?
        self.destroy
    end
end

Но это не работает.

Есть ли способ удалить запись, предназначенную для обновления на уровне модели?

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Есть способ Rails, чтобы справиться с этим.Это может быть сделано очень легко, но вам нужно сделать это из вашей модели магазина.В этой модели вставьте:

class Shop < ApplicationRecord
  accepts_nested_attributes_for :opening_times, allow_destroy: true, reject_if: :reject_opening_time?

  def reject_opening_time?(attributes)
    persisted = attributes[:id].present?
    time_values = attributes.slice(:morning, :evening).values
    without_time = time_values.any?(&:blank?)
    attributes.merge!(_destroy: true) if persisted and without_time
    without_time && !persisted # Return false so as to reject new opening_time if any time attributes are empty
  end
end

Теперь для каждой вложенной записи opening_time Rails будет оценивать атрибуты времени.Если какое-либо значение времени будет пустым, оно будет относиться к записи соответствующим образом.Если запись сохраняется, она добавит атрибут _destroy, который уничтожит вложенную запись при сохранении родительского элемента.Если запись не сохраняется, она будет отклонена (проигнорирована) при сохранении родительского элемента.

0 голосов
/ 19 февраля 2019

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

OpeningTime.where(morning:nil, evening:nil).destroy_all

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

Я думаю, что проблема с вашим текущим кодом заключается в том, что вы удаляете запись в before_save, поэтому это создает две проблемы:

1 / Что делать рельсам, если это не постоянная запись, ановый?Уничтожить не удастся, и с ним будет выполнен откат всей транзакции (взгляните на вашу консоль)

2 / Даже если запись сохранится, ее удаление будет работать, но действие сохранения, которое будет выполнено следующим,ошибка, также приводящая к откату.

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