rails_admin не позволит мне сохранить поле enum как ноль - PullRequest
1 голос
/ 25 сентября 2019

Модель:

class Reservation < ApplicationRecord
  # https://naturaily.com/blog/ruby-on-rails-enum
  enum recurrence: {
    daily: 0,
    weekly: 1,
    monthly: 2,
    annually: 3
  }, _prefix: :recurring

  belongs_to :user

  validates :name, :user_id, presence: true
  ...
end

Миграция:

class CreateReservations < ActiveRecord::Migration[5.2]
  def change
    create_table :reservations do |t|
      t.string 'name', null: false
      ...
      t.boolean 'recurring', default: false, null: false
      t.integer 'recurrence', index: true, allow_blank: true, default: nil # trying a lot of things here
      t.datetime 'expire_time'
      ...
    end
  end
end

Работает, как и ожидалось, в консоли:

2.4.5 :002 > res = Reservation.new(name: 'test', user_id: 1)
 => #<Reservation id: nil, name: "test", recurring: false, recurrence: nil, date: nil, start_time: nil, end_time: nil, expire_time: nil, user_id: 1, created_at: nil, updated_at: nil>

2.4.5 :003 > res.valid?
  User Load (0.7ms)  SELECT  "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
 => true

2.4.5 :004 > res.save
   (0.2ms)  BEGIN
  Reservation Create (0.5ms)  INSERT INTO "reservations" ("name", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["name", "test"], ["user_id", 1], ["created_at", "2019-09-24 20:42:40.933959"], ["updated_at", "2019-09-24 20:42:40.933959"]]
   (2.1ms)  COMMIT
 => true

2.4.5 :005 > res.reload
  Reservation Load (0.3ms)  SELECT  "reservations".* FROM "reservations" WHERE "reservations"."id" = $1 LIMIT $2  [["id", 5], ["LIMIT", 1]]
 => #<Reservation id: 5, name: "test", recurring: false, recurrence: nil, date: nil, start_time: nil, end_time: nil, expire_time: nil, user_id: 1, created_at: "2019-09-24 20:42:40", updated_at: "2019-09-24 20:42:40"> 

2.4.5 :006 > res.recurrence
 => nil 

И все же в Rails Admin, когда ясоздайте или отредактируйте запись, все они будут назначены первому перечислению.Даже когда я намеренно удаляю значение из формы, он все равно сохраняет запись с первым значением перечисления.

Rails Admin:

config.model Reservation do
    weight 2
    parent Event
    list do
      field :name
      field :display_date do
        formatted_value { bindings[:object].display_date }
      end
      field :recurrence, :active_record_enum # should be unnecessary, but trying everything
      field :expire_time
      field :user do
        label 'Creator'
        formatted_value { bindings[:object].user.name }
      end
    end
  end

Я пытался:

  • не индексирует это поле (думая, что администратору Rails нужно значение для индексированных столбцов)
  • обеспечение того, что `: active_record_enum` объявлено в` field: recurrence`

Как и предполагалось, вот соответствующий раздел журнала:

Started POST "/admin/reservation/new" for ::1 at 2019-09-25 10:09:50 -0400
Processing by RailsAdmin::MainController#new as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"VbhHM7YD+oQvwMYIQzMHyT5e0MXFFuN3pyH/1s6yM8n6kqKvywZ5E8zaABMKhOU+oWpfU1Kk55FWYjL9TzbkbQ==", "reservation"=>{"name"=>"logs", "date"=>"", "start_time"=>"", "end_time"=>"", "recurring"=>"0", "recurrence"=>"", "expire_time"=>"", "start_time_of_day"=>"", "end_time_of_day"=>"", "day_of_week"=>"", "date_of_month"=>"", "date_of_year"=>"", "user_id"=>"1"}, "return_to"=>"http://localhost:3000/admin/reservation", "_save"=>"", "model_name"=>"reservation"}
  User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (0.2ms)  BEGIN
  User Load (0.6ms)  SELECT  "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Reservation Create (0.4ms)  INSERT INTO "reservations" ("name", "recurrence", "day_of_week", "date_of_month", "date_of_year", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"  [["name", "logs"], ["recurrence", 0], ["day_of_week", ""], ["date_of_month", ""], ["date_of_year", ""], ["user_id", 1], ["created_at", "2019-09-25 14:09:50.926864"], ["updated_at", "2019-09-25 14:09:50.926864"]]
   (1.3ms)  COMMIT
Redirected to http://localhost:3000/admin/reservation
Completed 302 Found in 26ms (ActiveRecord: 3.0ms)

И, конечно же, параметр "recurrence"=>"" преобразуется в ["recurrence", 0]

Кажется, это известная проблема , но если это законноошибка, мне все еще нужна помощь с обходным путем.Кто-нибудь уже решил это?

Ответы [ 2 ]

1 голос
/ 25 сентября 2019

Технически это работает, но я думаю, что это не идеальное решение:

Если вы объявляете свое перечисление как хеш (не массив) и ничего не присваиваете 0, это работает.

В моем случае enum recurrence: { daily: 0, weekly: 1, monthly: 2, annually: 3 } становится enum recurrence: { daily: 1, weekly: 2, monthly: 3, annually: 4 }

В журналах показано, что параметр не передан в SQL:

Started POST "/admin/reservation/new" for ::1 at 2019-09-25 10:21:17 -0400
Processing by RailsAdmin::MainController#new as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"Joyg5VuquwMMKg+ps2zg9t+8r0DZ0iOIkqRlk1cBkemJpkV5Jq84lO8wybL62wIBQIgg1k5gJ25j56i41oVGTQ==", "reservation"=>{"name"=>"test3", "date"=>"", "start_time"=>"", "end_time"=>"", "recurring"=>"0", "recurrence"=>"", "expire_time"=>"", "start_time_of_day"=>"", "end_time_of_day"=>"", "day_of_week"=>"", "date_of_month"=>"", "date_of_year"=>"", "user_id"=>"1"}, "return_to"=>"http://localhost:3000/admin/reservation", "_save"=>"", "model_name"=>"reservation"}
  User Load (1.2ms)  SELECT  "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (0.2ms)  BEGIN
  User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Reservation Create (1.3ms)  INSERT INTO "reservations" ("name", "day_of_week", "date_of_month", "date_of_year", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id"  [["name", "test3"], ["day_of_week", ""], ["date_of_month", ""], ["date_of_year", ""], ["user_id", 1], ["created_at", "2019-09-25 14:21:17.091292"], ["updated_at", "2019-09-25 14:21:17.091292"]]
   (5.7ms)  COMMIT

Параметр содержит "recurrence"=>"",но INSERT INTO не имеет массива для recurrence, как это было раньше.

И я подтвердил в консоли:

2.4.5 :001 > res = Reservation.first
  Reservation Load (0.4ms)  SELECT  "reservations".* FROM "reservations" ORDER BY "reservations"."id" ASC LIMIT $1  [["LIMIT", 1]]
 => #<Reservation id: 4, name: "test3", date: nil, start_time: nil, end_time: nil, recurring: false, recurrence: nil, expire_time: nil, start_time_of_day: nil, end_time_of_day: nil, day_of_week: "", date_of_month: "", date_of_year: "", user_id: 1, created_at: "2019-09-25 14:21:17", updated_at: "2019-09-25 14:21:17"> 
2.4.5 :002 > res.recurrence
 => nil 

Однако мне кажется, что яЯ просто передаю запрещенное значение и позволяю Rails отклонить его.Это все еще кажется проблемой для Rails Admin, особенно с целочисленными перечислениями.

0 голосов
/ 26 сентября 2019

Это может быть ограничение использования хэшей, потому что nil значения должны работать .Поскольку вы отображаете эти значения в 0-индексированные значения, вы должны просто использовать массив символов.Документация ActiveRecord :: Enum (ссылка выше) гласит:

Обратите внимание, что при использовании массива неявное отображение значений в целые числа базы данных выводится из порядка следования значений в массиве.В этом примере: active отображается в 0 как первый элемент, а: archived отображается в 1. В общем случае i-й элемент отображается в базе данных i-1.

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

...