Rails 3.1+ nested form model not rendering properly - ruby-on-rails

I have a basketball app, where a Roster has many Players, and a Player belongs to a Roster.
Roster.rb
class Roster < ActiveRecord::Base
has_many :players
accepts_nested_attributes_for :players
attr_accessible :class_year, :jersey_number, :player_id, :team_id
end
Player.rb
class Player < ActiveRecord::Base
has_many :gamelogs
belongs_to :rosters
validates_presence_of :first_name, :last_name
attr_accessible :first_name, :last_name, :active
end
And my view that is only rendering first part of the form, but NOT the nested one
<div class="well">
<h2>New Player</h2>
<%= simple_form_for #new_player, :html => { :class => 'form-horizontal' } do |f| %>
<%=f.simple_fields_for :players do |x|%>
<%= x.input :first_name %>
<%= x.input :last_name %>
<%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%>
</div>
Image of it not working:
http://i.stack.imgur.com/Uoirp.png
I am using Simple_Form 2.0 and Twitter Boot Strap. Is there something I am not seeing? I feel like this should be simple, but I can't seem to figure out why it is not rendering. Thanks in advance.

You need an equal sign on your fields_for block:
<%= f.simple_fields_for :players do |x| %>
Edit:
All of this is assuming that #new_player == Roster.new
I had to do this with Formtastic, so it may be similar with Simple Form.
Looking at the source, it gives you an option to pass the nested object down to the nested form:
def simple_fields_for(record_name, record_object = nil, options = {}, &block)
So try doing something like this:
<%= f.simple_fields_for :players, #new_player.players.build do |x| %>

Related

Rails has_many :through create association and associated model on parent "show" view

I have three models in my rails 5 application... What I want to do is to be able to create a note on the person's "show" view, then the note should automatically link to that person and any other person I choose to attach the note to.
Here's where I got up to
Note
class Note < ApplicationRecord
has_many :person_notes
has_many :people, through: :person_notes
accepts_nested_attributes_for :person_notes
end
Person Note (Join table)
class PersonNote < ApplicationRecord
belongs_to :person
belongs_to :note
end
Person
class Person < ApplicationRecord
has_many :person_notes
has_many :notes, through: :person_notes
accepts_nested_attributes_for :person_notes
accepts_nested_attributes_for :notes
end
In my "show" section of my "people" controller I have the following:
def show
#notep = Note.new()
#person.notes << #notep
end
This is creating a join of a new note to my person record every time I open the page (obviously i only want the join to happen on the note I have created.)
I have rendered this in a modal as a partial in my "show" view (there is an "end" and a submit button but it's in between 3 divs and I know they weren't the cause of the issue so i didn't include them.:
<%= simple_form_for(#notep, remote: true) do |f| %>
<%= f.error_notification %>
<%= f.input :subject %>
<%= f.input :note %>
<%= f.input :date, html5: true %>
<div class="input-field">
<%= f.check_box :isalert, :id => "alert" %>
<%= f.label :isalert, :for => "alert" %>
</div>
<div class="input-field">
<%= f.check_box :archived, :id => "archived" %>
<%= f.label :archived, :for => "archived" %>
</div>
<div class="input-field">
<%= f.check_box :deleted, :id => "deleted" %>
<%= f.label :deleted, :for => "deleted" %>
</div>
<%= f.input :datecreated, html5: true %>
<%= f.input :user_id %>
<%= f.simple_fields_for :person_notes do |builder| %>
<%= builder.association :person, label_method: :lstfstfullname %>
<%= builder.input :deleted %>
<%= builder.input :datecreated, html5: true %>
<%= builder.input :user_id %>
<% end %>
You can probably tell I'm a total newb, but I'd appreciate any help I can get.
Thanks,
Leah
If I'm understanding this correctly, you'll want a separate Notes controller and create action to handle note creation. Then in your People show view, you can add a form and input field that submits to NotesController#create.

Cocoon - Wrong number of arguments (1 for 0) for look-up or create :belongs_to

Following the Cocoon wiki for implementing The look-up or create :belongs_to I'm receiving the error: wrong number of arguments (1 for 0). I'm not exactly sure what its referring to being that I'm following the tutorial verbatim aside from using slim as my precompiler. Here's what my code looks like:
Models
class Project < ActiveRecord::Base
belongs_to :user
has_many :tasks
accepts_nested_attributes_for :tasks, :reject_if => :all_blank, :allow_destroy => true
accepts_nested_attributes_for :user, :reject_if => :all_blank
end
class User < ActiveRecord::Base
has_many :projects
end
Projects Form
<%= simple_form_for #project do |f| %>
<%= f.input :name %>
<%= f.input :description %>
<h3>Tasks</h3>
<div id="tasks">
<%= f.simple_fields_for :tasks do |task| %>
<%= render 'task_fields', :f => task %>
<% end %>
<div class="links">
<%= link_to_add_association 'add task', f, :tasks %>
</div>
</div>
<div id="user">
<div id="user_from_list">
<%= f.association :user, collection: User.all(:order => 'name'), :prompt => 'Choose an existing user' %>
</div>
<%= link_to_add_association 'add a new person as owner', f, :user %>
</div>
<%= f.submit %>
<% end %>
Projects Controller
...
def project_params
params.require(:project).permit(:name, :description, tasks_attributes: [:id, :description, :done, :_destroy], user_attributes: [:id, :name])
end
Backtrace
app/views/projects/_form.html.erb:16:in `block in _app_views_projects__form_html_erb___3132123068035883478_70337216288160'
app/views/projects/_form.html.erb:1:in `_app_views_projects__form_html_erb___3132123068035883478_70337216288160'
app/views/projects/new.html.erb:3:in `_app_views_projects_new_html_erb__2418839848133678570_70337176808940'
ActiveRecord#all has been changed in rails 4 - this is now doing what scoped used to do. It does not expect any extra params. Instead of User.all(order: 'name') do:
User.order(:name)

Nested form in many to many relationship in rails 4

I have a model Contact which has a many-to-many relationship with Company:
class Contact < ActiveRecord::Base has_many :contactcompanies
has_many :companies, through: :contactcompanies
Company model:
class Company < ActiveRecord::Base
has_many :contactcompanies
has_many :contacts, through: :contactcompanies
ContactCompany:
class ContactCompany < ActiveRecord::Base
belongs_to :company
belongs_to :contact
contacts_controller.rb:
def new
#contact = Contact.new
#all_companies = Company.all
#contact_company = #contact.contactcompanies.build
end
contact create form where I want to have a multiple select for companies:
<%= form_for #contact do |f| %>
<%= f.label :first_name %>
<%= f.text_field :first_name %>
<%= f.label :last_name %>
<%= f.text_field :last_name %>
<%= f.label :image_url %>
<%= f.text_field :image_url %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= fields_for(#contact_company) do |cc| %>
<%= cc.label "All Companies" %>
<%= collection_select(:companies, :id, #all_companies, :id, :name, {}, { :multiple => true }) %>
<% end %>
<div class="form-action">
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
contacts_path, :class => 'btn' %>
</div>
<% end %>
My issue is when I go to /contacts/new I get this error:
Circular dependency detected while autoloading constant Contactcompany
Any ideas? I'm searching for hours without success. Thanks
You have declared your class as "ContactCompany"
This implies:
has_many :contact_companies
has_many :contacts, through: :contact_companies
Without the underscore, it is looking for a class named Contactcompany, which does not exist.

Rails 3.1+ Simple Nested Form validation and Twitter Bootstrap control states

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 %>

Rails 3.1 not rendering the fields_for from nested_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

Resources