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?