2014-09-02 50 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 %> 

現在,當我嘗試保存而沒有輸入任何信息時,所有正確的錯誤都顯示出來。另外,當我輸入所有需要的用戶數據並將所有組織字段留空時,將顯示正確的組織相關驗證錯誤,並且不會創建用戶記錄。像我現在需要的那樣工作。