Reputation: 25415
I'm new to rails, and I'm not sure how to set up a combobox so that it can be shown as "required" in the browser. I have a Product
and a Location
, and location should be required in a product:
class Product < ApplicationRecord
belongs_to :location
validates :location, presence: true
end
class Location < ApplicationRecord
has_many :products
end
In my new product form, I have a helper that shows that the field is required, but I'm not sure how best to do that with this associated location. When I try to map it to the :location
attribute like this:
<%= form_for @product do |f| %>
<%= show_label f, :location %>
<%= f.collection_select :location, @locations, :id, :name, include_blank: true %>
<%= f.submit %>
<% end %>
# helper
def show_label(f, attr)
required = f.object.class.validators_on(attr)
.any? { |v| v.kind_of?(ActiveModel::Validations::PresenceValidator) }
label = attr.to_s + required ? '*' : ''
label
end
...the show_label
helper correctly sees that :location
is required, but the model itself fails to validate after the form is posted because location here is a string (the :id of the location) rather than an actual Location
.
When I instead use :location_id
:
<%= f.collection_select :location_id, @locations, :id, :name, include_blank: true %>
then show_label
doesn't see that :location_id
is a required attribute so I don't get the required field annotation, but the location gets correctly saved when the model is saved.
What's the right way to render a combobox so I can both recognize if it's a required field AND allow my controller to save my Product? I feel like I'm probably missing something that competent Rails people all just know.
Upvotes: 0
Views: 470
Reputation: 7001
There are a bunch of posts on the differences between validating the association and validating the _id
column, but the rough idea should be to validate both the _id
column and the association.
Upvotes: 1
Reputation: 15838
Try using validates :location_id, presence: true
. It's not the same as the other validation (you could set an id that does not exist, it will be valid because it's present but it will be an invalid location), so leave the :location
validation too.
Upvotes: 2