2014-09-02 67 views
0

我有两个模型之间的belongs_tohas_many关联。我有一个创建用户的用户创建表单,并在创建过程中创建一个组织并将其关联。我有一个组织名称的存在验证。如果验证失败,我想OrganiationName cannot be blank错误添加到User具有的相同散列的错误消息。基本上,创建一个错误消息列表。Rails 4 - 显示嵌套关联的错误

这里是我的模型:

class User < ActiveRecord::Base 
    devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, :lockable, :timeoutable 

    belongs_to :organization 

    validates_presence_of :display_name 
end 

class Organization < ActiveRecord::Base 
    has_many :users, dependent: :destroy 

    accepts_nested_attributes_for :users, :allow_destroy => true 

    validates_presence_of :name 
end 

这里是我创建行动:

def create 
    @user = User.new(sign_up_params) 
    if params[:user][:organization][:access_code].blank? 
    # create new organization 
    @access_code = "#{SecureRandom.urlsafe_base64(16)}#{Time.now.to_i}" 
    @organization = Organization.create(name: params[:user][:organization][:name], access_code: @access_code) 
    @user.organization_id = @organization.id 
    @user.is_admin = true 
    else 
    # try and add someone to an organization 
    @organization = Organization.find(:all, conditions: ["name = ? AND access_code = ?", params[:user][:organization][:name], params[:user][:organization][:access_code]]) 
    if @organization.empty? 
     flash.now[:error] = "No organization has been found with that name and access code." 
     render :new 
     return 
    else 
     @user.organization_id = @organization.first.id 
    end 
    end 
    if @user.save 
    flash[:success] = "Your account has been successfully created! Check your email for a confirmation link to activate your account." 
    redirect_to sign_in_path 
    else 
    flash.now[:error] = "Something went wrong! Please try again." 
    render :new 
    end 
end 

这是我的观点:

<% provide(:title, 'Sign Up') %> 

<h1>Create Account</h1> 

<%= nested_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> 
    <%= render "shared/error_messages", obj: @user %> 

    <fieldset> 
    <legend>Account Information</legend> 
    <div class="form-group"> 
     <%= f.label :email %> 
     <%= f.email_field :email, class: "form-control", autofocus: true %> 
    </div> 
    <div class="form-group"> 
     <%= f.label :display_name, "Display Name" %> 
     <%= f.text_field :display_name, class: "form-control" %> 
    </div> 
    <div class="form-group"> 
     <%= f.label :password %> <% if @validatable %><i>(<%= @minimum_password_length %> characters minimum)</i><% end %> 
     <%= f.password_field :password, class: "form-control", autocomplete: "off" %> 
    </div> 
    <div class="form-group"> 
     <%= f.label :password_confirmation %> 
     <%= f.password_field :password_confirmation, class: "form-control", autocomplete: "off" %> 
    </div> 
    </fieldset> 
    <%= f.fields_for :organization do |o| %> 
    <fieldset> 
     <legend>Organization Information</legend> 
     <p> 
     <strong>Creating a New Organization:</strong> Fill out the Organization Name field, but leave the Access Code field blank.<br /> 
     <strong>Joining an Existing Organization:</strong> Fill out both the Organization Name and Access Code field, using the access code that you received from someone at your organization. 
     </p> 
     <div class="form-group"> 
     <%= o.label :name, "Organization Name" %> 
     <%= o.text_field :name, class: "form-control" %> 
     </div> 
     <div class="form-group"> 
     <%= o.label :access_code, "Organization Access Code" %> 
     <%= o.text_field :access_code, class: "form-control" %> 
     </div> 
    </fieldset> 
    <% end %> 
    <div class="form-actions"> 
    <%= f.submit "Create Account", class: "btn btn-primary" %> 
    <%= link_to "Cancel", :back %> 
    </div> 
<% end %> 

<%= render "users/shared/links" %> 

而且,这里的error_messages部分:

<% if obj.errors.any? %> 
    <div id="error_explanation"> 
    <h2>There are <%= pluralize(obj.errors.count, "error") %> errors with this form:</h2> 
    <ul> 
    <% obj.errors.full_messages.each do |msg| %> 
     <li><%= msg %></li> 
    <% end %> 
    </ul> 
    </div> 
<% end %> 

我得到User显示的错误应该是,而不是Organization。难道这只是通过@user部分?

+0

如果你只是传递给用户,那么你只会得到用户对象的错误消息,对吗?在你的控制器中,而不是说flash.now [:error] =“...”,为什么不直接说flash.now [:errors] = @ user.errors.full_messages + @ organization.errors。 full_messages? – stefvhuynh 2014-09-02 02:04:36

+0

Flash消息实际上与此问题无关。问题是我通过我相信的模型设置了ActiveModel验证。我假设通过'@ user'就可以了,组织错误将通过'@ user.organization'进入。 – ryanpitts1 2014-09-02 02:26:50

回答

0

好吧,我找出我的问题。似乎我可能有一些事情与模型协会倒退,或至少与accepts_nested_attributes

这里是我的最新车型:

class User < ActiveRecord::Base 
    devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, :lockable, :timeoutable 

    belongs_to :organization 

    accepts_nested_attributes_for :organization 

    validates_presence_of :display_name 
end 

class Organization < ActiveRecord::Base 
    has_many :users, dependent: :destroy 

    validates_presence_of :name 
end 

这是我更新我的控制器创建行动:

def create 
    @user = User.new(sign_up_params) 
    if params[:user][:organization_attributes][:access_code].blank? 
    # create new organization 
    @access_code = "#{SecureRandom.urlsafe_base64(16)}#{Time.now.to_i}" 
    @organization = Organization.create(name: params[:user][:organization_attributes][:name], access_code: @access_code) 
    @user.organization_id = @organization.id 
    @user.is_admin = true 
    else 
    # try and add someone to an organization 
    @organization = Organization.find(:all, conditions: ["name = ? AND access_code = ?", params[:user][:organization_attributes][:name], params[:user][:organization_attributes][:access_code]]) 
    if @organization.empty? 
     flash.now[:error] = "No organization has been found with that name and access code." 
     render :new 
     return 
    else 
     @user.organization_id = @organization.first.id 
    end 
    end 
    if @user.save 
    flash[:success] = "Your account has been successfully created! Check your email for a confirmation link to activate your account." 
    redirect_to sign_in_path 
    else 
    flash.now[:error] = "Something went wrong! Please try again." 
    render :new 
    end 
end 

这里是我的最新观点:

<% provide(:title, 'Sign Up') %> 

<h1>Create Account</h1> 

<%= nested_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> 
    <%= render "shared/error_messages", obj: @user %> 

    <fieldset> 
    <legend>Account Information</legend> 
    <div class="form-group"> 
     <%= f.label :email %> 
     <%= f.email_field :email, class: "form-control", autofocus: true %> 
    </div> 
    <div class="form-group"> 
     <%= f.label :display_name, "Display Name" %> 
     <%= f.text_field :display_name, class: "form-control" %> 
    </div> 
    <div class="form-group"> 
     <%= f.label :password %> <% if @validatable %><i>(<%= @minimum_password_length %> characters minimum)</i><% end %> 
     <%= f.password_field :password, class: "form-control", autocomplete: "off" %> 
    </div> 
    <div class="form-group"> 
     <%= f.label :password_confirmation %> 
     <%= f.password_field :password_confirmation, class: "form-control", autocomplete: "off" %> 
    </div> 
    </fieldset> 
    <% @user.build_organization unless @user.organization %> 
    <%= f.fields_for :organization do |o| %> 
    <fieldset> 
     <legend>Organization Information</legend> 
     <p> 
     <strong>Creating a New Organization:</strong> Fill out the Organization Name field, but leave the Access Code field blank.<br /> 
     <strong>Joining an Existing Organization:</strong> Fill out both the Organization Name and Access Code field, using the access code that you received from someone at your organization. 
     </p> 
     <div class="form-group"> 
     <%= o.label :name, "Organization Name" %> 
     <%= o.text_field :name, class: "form-control" %> 
     </div> 
     <div class="form-group"> 
     <%= o.label :access_code, "Organization Access Code" %> 
     <%= o.text_field :access_code, class: "form-control" %> 
     </div> 
    </fieldset> 
    <% end %> 
    <div class="form-actions"> 
    <%= f.submit "Create Account", class: "btn btn-primary" %> 
    <%= link_to "Cancel", :back %> 
    </div> 
<% end %> 

<%= render "users/shared/links" %> 

这里是我的更新error_messages部分(只显示上下文 - 更改的代码并不真正与问题相关):

<% if obj.errors.any? %> 
    <div id="error_explanation"> 
    <h2><%= pluralize(obj.errors.count, "error") %> was found with this form:</h2> 
    <ul> 
    <% obj.errors.full_messages.each do |msg| %> 
     <li><%= msg %></li> 
    <% end %> 
    </ul> 
    </div> 
<% end %> 

现在,当我尝试保存而没有输入任何信息时,所有正确的错误都显示出来。另外,当我输入所有需要的用户数据并将所有组织字段留空时,将显示正确的组织相关验证错误,并且不会创建用户记录。像我现在需要的那样工作。