Organization and User have a many-to-many relationship through Relationship. There's a joined signup form. The sign up form works in that valid information is saved while if there's invalid information it rolls back everything.
The problem is that the form does not display the error messages for the nested User object. Errors for Organization are displayed, the form correctly re-renders if there are errors for User, but the errors for User are not displayed.
Why are the errors when submitting invalid information for users not displayed? Any help is appreciated.
The signup form/view:
<%= form_for @organization, url: next_url do |f| %> <%= render partial: 'shared/error_messages', locals: { object: f.object, nested_models: f.object.users } %> ... fields for organization... <%= f.fields_for :users do |p| %> ...fields for users... <% end %> <%= f.submit "Register" %> <% end %> The shared error messages partial:
<% if object.errors.any? %> <div id="error_explanation"> <div class="alert alert-danger"> The form contains <%= pluralize(object.errors.count, "error") %>. </div> <ul> <% object.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> <% if defined?(nested_models) && nested_models.any? %> <div id="error_explanation"> <ul> <% nested_models.each do |nested_model| %> <% if nested_model.errors.any? %> <ul> <% nested_model.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> <% end %> <% end %> </ul> </div> <% end %> The controller method:
def new @organization = Organization.new @user = @organization.users.build end def create @organization = Organization.new(new_params.except(:users_attributes)) @organization.transaction do if @organization.valid? @organization.save begin @user = @organization.users.create!(users_attributes) @relationship = @organization.relationships.where(user: @user).first @relationship.update_attributes!(member: true, moderator: true) rescue raise ActiveRecord::Rollback end end end if @organization.persisted? if @organization.relationships.where('member = ? ', true).any? @organization.users.where('member = ? ', true).each do |single_user| single_user.send_activation_email end end flash[:success] = "A confirmation email is sent." redirect_to root_url else @user = @organization.users.build(users_attributes) if @organization.users.blank? render :new end end The Organization model:
has_many :relationships, dependent: :destroy has_many :users, through: :relationships, inverse_of: :organizations accepts_nested_attributes_for :users, :reject_if => :all_blank, :allow_destroy => true validates_associated :users The Relationship model:
belongs_to :organization belongs_to :user The User model:
has_many :relationships, dependent: :destroy has_many :organizations, through: :relationships, inverse_of: :users Update: If I add an additional line to def create as below, it seems to work, i.e., then it does display the error messages. However, then it for some reason doesn't save when valid information is submitted. Any ideas how to deal with that?
def create @organization = Organization.new(new_params.except(:users_attributes)) @user = @organization.users.new(users_attributes) @organization.transaction do ...
shared/error_messagespartial?