I'm writing a Rails frontend for inventory management. I want users to be able to register products, so I have:
class User < ActiveRecord::Base has_many :products # <snip> end
and
class Product < ActiveRecord::Base belongs_to :user # <snip> end
The problem is that products are created prior to being registered by a user. That is, it's perfectly acceptable to call Product.create
and just have it set the user_id
to nil
. As you can imagine, though, Rails doesn't support this out of the box:
> 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!'
I've thought about a bunch of kludgey workarounds, the most appealing of which is to have a NullUser
subclassing User
and use that to create products. But that still seems like a hack. What's the Rails Way with this?
Thanks.
The relevant migration:
class AddUseridToProducts < ActiveRecord::Migration def change add_column :products, :user_id, :integer end end
and later:
class Changeuseridtobeoptionalforproducts < ActiveRecord::Migration def change change_column :products, :user_id, :integer, null: true end end
They essentially do the same thing, the only difference is what side of the relationship you are on. If a User has a Profile , then in the User class you'd have has_one :profile and in the Profile class you'd have belongs_to :user .
If you set the :optional option to true, then the presence of the associated object won't be validated. By default, this option is set to false . otherwise it will be required associated object.
In Ruby on Rails, a polymorphic association is an Active Record association that can connect a model to multiple other models. For example, we can use a single association to connect the Review model with the Event and Restaurant models, allowing us to connect a review with either an event or a restaurant.
In Rails, an association is a connection between two Active Record models. Why do we need associations between models? Because they make common operations simpler and easier in your code. For example, consider a simple Rails application that includes a model for authors and a model for books.
Just an update for rails 5, if you want this kind of behavior you will need to pass this option:
belongs_to :user, optional: true
In Rails 5, whenever we define a belongs_to association, it is required to have the associated record present by default.
Update
If you still want to use the old behavior by default you can add the configuration to your application.rb file.
# /config/application.rb config.active_record.belongs_to_required_by_default = false
notice: there were some issues on early releases of Rails 5 with this configuration, but is currently fixed, tested on the release candidate 5.2.3.
Rails absolutely supports this out of the box, check your migrate, have you included a constraint such as :null => false
on the user_id
line? If so, take it out!
Edit: Or as @Rodrigo Dias states, reverse it to :null => true
.
Also, check that you don't have any validations on the user relation in the Product model.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With