Rails opcional pertenece a
Estoy escribiendo una interfaz Rails para la gestión de inventario. Quiero que los usuarios puedan registrar productos, así que tengo:
class User < ActiveRecord::Base
has_many :products
# <snip>
end
Y
class Product < ActiveRecord::Base
belongs_to :user
# <snip>
end
El problema es que los productos se crean antes de ser registrados por un usuario. Es decir, es perfectamente aceptable llamar a Product.create
y simplemente establecer el user_id
a nil
. Como se puede imaginar, sin embargo, Rails no soporta esto fuera de la caja:
> 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!'
He pensado en un montón de soluciones de kludgey, el más atractivo de que es tener una subclase NullUser
User
y usarla para crear productos. Pero eso todavía parece un truco. ¿Cuál es el camino de los Rieles con esto?
Gracias.
La migración pertinente:
class AddUseridToProducts < ActiveRecord::Migration
def change
add_column :products, :user_id, :integer
end
end
Y posteriores:
class Changeuseridtobeoptionalforproducts < ActiveRecord::Migration
def change
change_column :products, :user_id, :integer, null: true
end
end
3 answers
¿ Tiene una validación que requiere que el usuario esté presente? Si es así, quita eso.
Solo una actualización para rails 5, si quieres este tipo de comportamiento tendrás que pasar esta opción:
belongs_to :user, optional: true
En Rails 5, siempre que definamos una asociación belongs_to, es necesario tener el registro asociado presente por defecto.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-09 00:28:56
Rails absolutamente soporta esto fuera de la caja, marque su migración, ¿ha incluido una restricción como :null => false
en la línea user_id
? Si es así, ¡sácalo!
Editar: O como dice @Rodrigo Dias, invertirlo a :null => true
.
Además, compruebe que no tiene ninguna validación en la relación de usuario en el modelo de Producto.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-22 19:25:29