mrcolombo
mrcolombo

Reputation: 587

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: https://i.sstatic.net/8pvUc.png

The 2 of the required 4 fields submitted returns: https://i.sstatic.net/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!

Upvotes: 0

Views: 2224

Answers (2)

mober
mober

Reputation: 361

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 [email protected] %>
<%= f.simple_fields_for :player do |player_form| %>
...
<% end %>

Upvotes: 2

Terry
Terry

Reputation: 14219

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

Upvotes: 0

Related Questions