Миграция Rails с уникальным индексом, null: false, по умолчанию: «»

#ruby-on-rails #ruby

#ruby-on-rails #ruby

Вопрос:

У меня есть subdomain столбец в моей project таблице. Я разрешаю премиум-пользователям обновлять поддомен, а бесплатные пользователи не могут его обновлять. Мне также нужны уникальные поддомены, чтобы не было конфликта. В настоящее время у меня такая настройка:

Миграция проекта

 create_table :projects, id: uuid do |t|
  t.string :name, null: false, default: ""
  t.string :subdomain, null: false, default: ""
end

add_index :projects, :subdomain, unique: true
 

project.rb (модель)

 validates :subdomain, length: { maximum: 63 }, uniqueness: { case_sensitive: false, allow_blank: true }
 

Проблема в том, что если бесплатный пользователь обновляет атрибут проекта table name , subdomain он передается как пустая строка param , а при моей текущей настройке другой бесплатный пользователь не сможет обновить project таблицу, поскольку пользователь также передаст пустую строку для subdomain столбца и приведет к ошибке.

В настоящее время я исправляю эту ошибку, перезаписывая subdomain= метод, удаляя null: false и удаляя default: "" из subdomain столбца

 def subdomain=(value)
  default_value = value.blank? ? nil : value
  super(default_value)
end
 

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

Комментарии:

1. Вы должны добавить уникальное ограничение для имени И поддомена вместе взятых.

2. Зачем мне добавлять уникальное ограничение для name ? Мне не нужен уникальный name столбец.

3. Вы разрешаете, чтобы имя проекта было одинаковым? Есть ли вероятность, что имя проекта и поддомен двух разных пользователей будут одинаковыми?

4. Поддомен должен быть уникальным, а название проекта может быть одинаковым.

Ответ №1:

Вы можете попробовать это:

  • Добавить subdomain поле с обнуляемым значением с уникальным индексом; null: true
  • Добавить:
    validates :subdomain, length: { maximum: 63 }, uniqueness: { case_sensitive: f 
 alse }, allow_nil: true

 

Комментарии:

1. Да, это то, что я пытался.

2. @AbeidAhmed вы можете попробовать использовать before_save метод, который будет проверять subdomain = subdomain.present? ? subdomain : nil

3. Рассмотрит ваше решение.