Как найти постоянный идентификатор в миграции Rails? - PullRequest
0 голосов
/ 10 июня 2019

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

Я определил константу в модели User.rb:

USER_TYPE = [
    { id: 1, name: "User" },
    { id: 2, name: "Admin" },
    { id: 3, name: "Super Admin" }
  ].freeze

и сгенерированная новая миграция

class AddAccountTypeIdInAccounts < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :user_type_id, :integer, :default => ?
  end
end

Что должно быть вместо '?' сохранить USER_TYPE с идентификатором 1 и именем «Пользователь» из константы в качестве значения по умолчанию для нового пользователя?

Ответы [ 2 ]

3 голосов
/ 10 июня 2019
add_column :users, :user_type_id, :integer, :default => 1

Серьезно, почему вы хотите определить значение по умолчанию для константы, которая живет в коде приложения? Миграция - это то, что вы будете запускать в определенный момент времени, а не код, который вы будете поддерживать в дальнейшем. Нет смысла ссылаться на код приложения при переносе, потому что приложение будет развиваться и ссылки будут меняться. Вы не хотите поддерживать миграцию.

Конечно, вы также можете ссылаться на значение, хранящееся в этой константе, возможно, это послужит вам документацией. В этом случае:

add_column :users, :user_type_id, :integer, :default => User::USER_TYPE.first[:id]

(Не уверен, если USER_TYPE определено внутри class User; если нет, пропустите User:: выше.)

0 голосов
/ 10 июня 2019

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

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

Опция выше не масштабируется.

Вам, вероятно, следует разрешить использование по умолчанию nil при миграции и использовать ActiveRecord обратные вызовы или, что еще лучше, другой модуль (сервис или действие), который позаботится о действии create для вас и установит значение по умолчанию.

# models/user
# option 1
class User < ApplicationRecord
  USER_TYPE = [
    { id: 1, name: "User" },
    { id: 2, name: "Admin" },
    { id: 3, name: "Super Admin" }
  ].freeze

  before_create do
    self.user_type_id = USER_TYPE.first[:id]
  end
end

# services/user_creator_service
# option 2
class UserCreatorService
  def self.call(user)
    user.user_type_id = User::USER_TYPE.first[:id]
    user.save
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...