I know this question has been asked a bunch of times. I already have nested fields_for in my app many times w/o issue so I'm confused as to why its not working this time. I apologize for bringing this topic up again.
I have a user model. A user can have many accounts. To prevent a user from existing w/o at least one account I have a semantic_fields_for nested in the new user form with just one input for setting account role_id.
class User
attr_accessible :accounts_attributes
has_many :accounts, :dependent => :destroy
accepts_nested_attributes_for :accounts
class Account
attr_accessible :role_id, :user_id, :status
belongs_to :role
belongs_to :user
users/new
<%= f.semantic_fields_for :accounts do |account| %>
<%= account.input :role, :as => :select, :collection => #roles, :label => "Account" %>
<% end %>
So, to recap: I have the association set up between users and accounts, users model includes accepts_nested_attributes_for, users model includes attr_accessible :accounts_attributes, semantic_fields_for is set up correctly. The error I get is:
Can't mass-assign protected attributes: accounts
The stack trace from the submitted form includes all the correct variables. Account role_id is being set correctly by the nested attribute. The record is simply being rejected for mass-assignment error but it sure seems my attributes are all properly protected.
Using Rails 3.2.3 and Formtastic 2.2.
EDITED
class UsersController
def new
#user = User.new
#user.accounts.build
end
users/new
<%= semantic_form_for :user, :url => users_path do |f| -%>
<%= f.inputs do %>
<%= f.input :name %>
<%= f.input :username %>
<%= f.input :email %>
<%= f.input :password, :as => :password %>
<%= f.input :password_confirmation, :label => "Confirm Password", :as => :password %>
<%= f.input :school_id, :as => :hidden, :input_html => {:value => #school.id} %>
<%= f.semantic_fields_for :accounts do |account| %>
<%= account.input :role_id, :as => :select, :collection => #roles %>
<% end %>
<%- end -%> <%# END f.inputs do %>
<%= submit_tag 'Create User', :class => "button" %>
<%- end -%> <%# END form %>
GOT IT!! I removed :url => and changed :user to #user in the semantic_form_for block... I guess the way I had it was causing the params[:account] to set off mass assignment
Try adding this to your to your User class
attr_accessible :accounts_attributes
Related
During registration of a new user with Devise, I need to create a new Family object link to this new user at the same time (the user being the head of the family).
My family model:
belongs_to user
My user model:
attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :family
has_one :family
accepts_nested_attributes_for :family
In devise/registration/new.html.erb
<%= simple_form_for([resource, Family.new], :as => resource_name, :url => registration_path(resource_name), :html => {:class => 'form-vertical' }) do |f| %>
<%= f.error_notification %>
<%= display_base_errors resource %>
<%= f.input :name, :autofocus => true %>
<%= f.input :email, :required => true %>
<%= f.input :password, :required => true %>
<%= f.input :password_confirmation, :required => true %>
<% f.fields_for :family do |family_form| %>
<p><%= family_form.label :name %></p>
<p><%= family_form.text_field :name %></p>
<% end %>
<%= f.button :submit, 'OK', :class => 'btn-primary' %>
<% end %>
But this is not working, I find a couple of question like this but I did not manage to fix that.
Any idea ?
UPDATE 1
I got the following error:
undefined method `email' for #<Family:0x007f892a12c310>
Family is a model that do not have any email, just a name. I just need to be able to create a new Family object with a name when creating a new user (and link it to the user as well).
UPDATE 2
I have added resource.build_family in my registrations controller. The family object is correctly created and associated to the user (I can display <%= resource.family %> in new.html.erb for debugging), but still no form displayed for the family.
You need the equal sign in the <%=fields_for
<%= f.fields_for :family do |family_form| %>
<p><%= family_form.label :name %></p>
<p><%= family_form.text_field :name %></p>
<% end %>
And in your user model you need to make the :family_attribues accessible and not :family
attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :family_attributes
has_one :family
accepts_nested_attributes_for :family
If you're getting undefined method 'email' for #<Model:0x007f892a12c310>:
You need to overwrite Devise::RegistrationsController as described in the docs: https://github.com/heartcombo/devise#configuring-controllers. E.g.
class Users::RegistrationsController < Devise::RegistrationsController
def new
super do |resource|
resource.build_<model>
end
end
end
And you must only specify resource in form_for: simple_form_for(resource, ... instead of simple_form_for([resource, Model.new], ...
I need some help with handling validations with Twitter Bootstrap properly. The validations are working properly, the issue is Twitter Bootstrap Flash screen. This is what I mean:
No fields filled out and submitted returns: http://i.stack.imgur.com/8pvUc.png
The 2 of the required 4 fields submitted returns: http://i.stack.imgur.com/J6lCi.png
(notice that it doesn't flash the errors)
I have a basketball app where a Player can be on many Rosters(for player roster archiving purposes) and a Roster can have many Players.
Roster.rb
class Roster < ActiveRecord::Base
belongs_to :team
has_many :rosterizes
has_many :players, :through => :rosterizes
accepts_nested_attributes_for :players
validates_presence_of :jersey_number, :class_year
attr_accessible :jersey_number, :class_year, :players, :team_id, :players_attributes
end
Rosterizes.rb(poorly named I know...)
class Rosterize < ActiveRecord::Base
belongs_to :player
belongs_to :roster
attr_accessible :player_id, :roster_id
end
Player.rb
class Player < ActiveRecord::Base
has_many :rosterizes
has_many :rosters, :through => :rosterizes
validates_presence_of :first_name, :last_name
attr_accessible :first_name, :last_name, :active
end
_add_player_form.html.erb
(nested form)
<%= simple_nested_form_for #roster, :url =>player_added_team_path, :html => { :class => 'form-horizontal' } do |f| %>
<%= f.simple_fields_for :players, #roster.players.build do |x| %>
<%= x.input :first_name %>
<%= x.input :last_name %>
<%= x.input :active, :as => :hidden, :input_html => {:value => true} %>
<%end%>
<%=f.input :class_year %>
<%=f.input :jersey_number %>
<%=f.input :team_id, :as => :hidden, :input_html => {:value => params[:id]}%>
<div class="well">
<%= f.button :submit, :class => 'btn-primary icon-plus-sign btn-success', :value => "Add To Team" %>
</div>
<%end%>
Thanks for the help in advance!
SOLUTION
My problem is that every time the view was loaded, it was building a new form, thus never getting back the errors on the rollback
I made a change to my controller that builds for the nested form
Controller
def add_player
...
#new_player = #roster.players.build
end
And made the change accordingly to the view
_add_player_form.html.erb
<%= f.simple_fields_for :players, #new_player do |x| %>
...
<%end%>
This did the trick, thanks Mober!
the reason why only the first level validation is shown an the associated not is fairly simple... You do a <%= f.simple_fields_for :players, #roster.players.build do |x| %> which buildes the association ALWAYS new when the sites's rendered. What you want to is building the association only if it does not exists yet...
<% #roster.players.build if !#roster.players %>
<%= f.simple_fields_for :player do |player_form| %>
...
<% end %>
Twitter Bootstrap doesn't actually validate anything, it just provides styling for validation classes (error, success, etc).
Now, I'm not a Ruby expert by any means but it looks like you are ending your form early:
<%= f.simple_fields_for :players, #roster.players.build do |x| %>
<%= x.input :first_name %>
<%= x.input :last_name %>
<%= x.input :active, :as => :hidden, :input_html => {:value => true} %>
<%end%> <---- here
<%=f.input :class_year %>
<%=f.input :jersey_number %>
<%=f.input :team_id, :as => :hidden, :input_html => {:value => params[:id]}%>
Should be this?
<%= f.simple_fields_for :players, #roster.players.build do |x| %>
<%= x.input :first_name %>
<%= x.input :last_name %>
<%= x.input :active, :as => :hidden, :input_html => {:value => true} %>
<%= f.input :class_year %>
<%= f.input :jersey_number %>
<%= f.input :team_id, :as => :hidden, :input_html => {:value => params[:id]}%>
<% end %>
I am new to rails and using a combination of formtastic, activeadmin,sti and polymorphic associations to build a form
When I I can create a nested form with the address parent with no problem, but when i introduce STI and attempt to build_origin_address instead of build_address, that is when I get the error below when loading the edit view
NameError in Admin/leads#edit
Showing .../app/views/admin/leads/_form.erb where line #3 raised:
uninitialized constant Lead::OriginAddress
Models:
class Address < ActiveRecord::Base
belongs_to :addressable, :polymorphic => true
belongs_to :lead
validates :line1, :presence => true, :length => {:minimum => 2}
attr_accessible :line1, :line2, :city, :state, :zip, :country
end
class OriginAddress < Address
end
class DestinationAddress < Address
end
class Lead < ActiveRecord::Base
has_one :origin_address, :dependent => :destroy, :as => :addressable
accepts_nested_attributes_for :origin_address, :allow_destroy => true
end
partial used in edit view:
<%= semantic_form_for [:admin, #lead] do |f| %>
<% #lead.build_origin_address unless #lead.origin_address %>
<%= f.inputs :name => "Lead Info" do %>
<%= f.input :first_name %>
<%= f.input :last_name %>
<% end %>
<%= f.semantic_fields_for :origin_address do |origin| %>
<%= origin.inputs :name => "Origin Address" do %>
<%= origin.input :line1 %>
....
<% end %>
<% end %>
<%= f.buttons do %>
<%= f.commit_button %>
<% end %>
<% end %>
I think you must define #lead before your form.
I have a project model that has_many :tasks. I added a nested resource in rails 3.1 and try now with the nested_form gem to be able to add/delete tasks when editing a project.
I used nested_form before in another Rails3 application and it worked fine, but now my fields_for part does not render anything.
Here is my code:
#project.rb
class Project < ActiveRecord::Base
attr_accessible :nr, :name, :client_id, :project_status_id, :hidden, :active, :description, :tasks_attributes
has_many :tasks, :dependent => :destroy
accepts_nested_attributes_for :tasks, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
end
#task.rb
class Task < ActiveRecord::Base
belongs_to :project
end
#views/projects/_form.html.erb
<%= simple_nested_form_for #project do |form| %>
<%= form.input :nr, :label => 'Nr' %>
<%= form.input :name, :label => 'Name' %>
<%= form.association :client, :collection => Client.all(:order => 'name'), :prompt => "Choose a Client" %>
<%= form.input :description, :label => 'Description' %>
<%= form.input :active, :label => 'Active' %>
<%= form.input :hidden, :label => 'Hidden' %>
<div class="task_fields">
<%= form.fields_for :tasks do |task_form| %>
<%= task_form.input :name %>
<%= task_form.input :description %>
<%= task_form.input :deadline %>
<%= task_form.link_to_remove "Remove this task" %>
<p><%= form.link_to_add "Add a task", :tasks %></p>
<% end %>
</div>
<div class="actions">
<%= form.button :submit %>
</div>
<% end %>
and in my routes:
resources :posts do
resources :comments
end
but when I visit the page in my browser the
<div class="task_fields"></div>
is rendered empty. no fields_for and whatsoever. the nested_form.js is loaded and I point in my GEMFILE to gem "nested_form", :git => 'https://github.com/fxposter/nested_form.git', as I read somewhere I need to do this in order to get simple_form support. I tried also to change simple_nested_form_for to only nested_form_for with no effect.
Any help higly appreciated
In projects#new, you have to initialize at least one task otherwise your fields_for part won't display anything.
# projects_controller.rb
def new
#project = Project.new
#project.tasks.new
end
If you want more than one task:
n.times { #project.tasks.new } # replace n with the number of tasks needed
I have the following two simple models for users and user groups:
class User < ActiveRecord::Base
belongs_to :user_group
end
and
class UserGroup < ActiveRecord::Base
has_many :users
end
I use the following formtastic code to draw my form for the UserGroup model:
<% semantic_form_for [:system, #user_group] do |form| %>
<% form.inputs do %>
<%= form.input :name %>
<%= form.input :description %>
<%= form.input :users, :as => :check_boxes %>
<% end %>
<% form.buttons do %>
<%= form.commit_button "Save Group" %>
<% end %>
<% end %>
The form displays nicely and lists all Users in the system with checkbox checked for the users that currently belong to the UserGroup. Currently, the only attribute of the user in the list that it displays is the "username".
How is it determining to use the "username" method to get the label for each user?
How do I change it to show the "first_name" and "last_name" attributes?
Thanks
Looks like this is accomplished through formtastic's :label_method. Found in this answer.
<%= form.input :users, :label_method => :username, :as => :check_boxes %>
or
<%= form.input :users, :label_method => Proc.new { |x| "#{x.first_name} #{x.last_name}" }, :as => :check_boxes %>