Reputation: 3658
I'm writing a form for users to register their products with. I already have class User has_many :products
and class Product belongs_to :user; attr_accessible :serial_number
. So the idea is that the user enters the serial number in the form and I call @user.products << Product.find_by_serial_number params[:serial_number]
or somesuch.
It seemed sensible to add this as a register action to the UsersController
:
resources :users do
member do
get 'register'
end
end
And I have the following in register.html.erb
:
5: <%= render 'shared/error_messages' %>
6:
7: <%= f.label :serial_number, "Serial number" %>
8: <%= f.text_field :serial_number %>
9:
10: <%= f.submit "Register product" %>
11: <% end %>
This throws the error:
undefined method `serial_number' for #<User:0x000000060b1d40>
extracted source (around line #8):
...
So...a) How do I stop this error? b) Umm...what's going to happen after the submit button is pressed? I'm assuming it'll call the update
action (which is also used by the edit form)...should I make that fatter to deal with both possiblities? Or make a new action? (If so, how do I reroute the form to point to that?) c) Error-handling (putting in an invalid serial number) is best handled in the controller, not the model, right?
Thanks.
Upvotes: 5
Views: 4353
Reputation: 26193
The error being thrown indicates that there's no method serial_number
for the User
model... which there isn't. The method is actually attached to the Product
model, but the form in register.html.erb
is for User
. You can resolve this by using a nested form.
First, ensure that User
can accept nested attributes for Product
:
# app/models/user.rb
has_many :products
accepts_nested_attributes_for :products
Then, make your form into a nested form:
# app/views/users/register.html.erb
<%= form_for(@user) do |f| %>
<%= f.fields_for :products do |e| %>
<%= e.label :serial_number, "Serial number" %>
<%= e.text_field :serial_number %>
<% end %>
<%= f.submit "Register product" %>
<% end %>
Upvotes: 1
Reputation: 8006
You can only use the form helper for attributes of the model. In this case you will need to use the full method.
= label_tag :serial_number, 'Serial number'
= text_field_tag :serial_number
Upvotes: 4