Ответ 1
У вас есть проверка, требующая присутствия пользователя? Если это так, удалите это.
Я пишу интерфейс Rails для управления запасами. Я хочу, чтобы пользователи могли регистрировать продукты, поэтому у меня есть:
class User < ActiveRecord::Base
has_many :products
# <snip>
end
а также
class Product < ActiveRecord::Base
belongs_to :user
# <snip>
end
Проблема в том, что продукты создаются до регистрации пользователем. То есть вполне приемлемо вызвать Product.create
и просто установить user_id
в nil
. Однако, как вы можете себе представить, Rails не поддерживает это из коробки:
> Product.create!
(0.3ms) SELECT COUNT(*) FROM "products" WHERE "products"."type" IN ('Product')
(0.1ms) begin transaction
(0.1ms) rollback transaction
ActiveRecord::RecordInvalid: Validation failed: User can't be blank
from ~/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-3.2.13/lib/active_record/validations.rb:56:in 'save!'
Я думал о связке kludgey обходов, наиболее привлекательным из которых является иметь NullUser
подклассов User
и использовать его для создания продуктов. Но это все еще кажется взломом. Что такое Rails Way с этим?
Благодарю.
Соответствующая миграция:
class AddUseridToProducts < ActiveRecord::Migration
def change
add_column :products, :user_id, :integer
end
end
и позже:
class Changeuseridtobeoptionalforproducts < ActiveRecord::Migration
def change
change_column :products, :user_id, :integer, null: true
end
end
У вас есть проверка, требующая присутствия пользователя? Если это так, удалите это.
Просто обновление для rails 5, если вы хотите такое поведение, вам нужно будет передать эту опцию:
belongs_to :user, optional: true
В Rails 5 всякий раз, когда мы определяем ассоциацию own_to, требуется, чтобы соответствующая запись присутствовала по умолчанию.
Обновить
Если вы по-прежнему хотите использовать старое поведение по умолчанию, вы можете добавить конфигурацию в файл application.rb.
# /config/application.rb
config.active_record.belongs_to_required_by_default = false
обратите внимание: в ранних выпусках Rails 5 с этой конфигурацией были некоторые проблемы, но в настоящее время это исправлено, протестировано на версии-кандидате 5.2.3.
Rails абсолютно поддерживает это из коробки, проверьте свой перенос, включили ли вы ограничение, например :null => false
в строке user_id
? Если да, вытащите его!
Изменение: Или, как утверждает @Rodrigo Dias, отмените его на :null => true
.
Кроме того, убедитесь, что у вас нет валидации в отношении пользователя в модели продукта.