2014-03-04 39 views
0

我正在創建一個應用程序,通過它用戶將能夠創建一個帳戶。當他們創建一個賬戶時,他們將以相同的形式創建一個組織,然後將其綁定到他們的用戶。一旦該用戶創建了自己的帳戶(和一個組織),其他用戶將能夠創建一個帳戶並使用「訪問代碼」加入該組織。查看代碼可能會更好地解釋它。Rails - 右/更好的方式去belongs_to/has_many關係

我在SO上發帖的原因是因爲我有一種感覺,有比現在做的更好/更有效的方法。我正在使用nested_forms(也許不正確),我認爲我沒有正確地進行關聯,例如,我無法獲得編輯表單來填寫組織字段。

我正在使用魔法進行驗證。

users_controller.rb

def new 
    @user = User.new 
end 

def create 
    @user = User.new(user_params) 
    if params[:user][:organization][:name].blank? 
    flash.now[:error] = "You must specify an organization name." 
    render :new 
    else 
    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 
     user = login(@user.email, params[:user][:password]) 
     if user 
     flash[:success] = "Your account has been successfully created!" 
     redirect_to admin_dashboard_path 
     end 
    else 
     flash.now[:error] = "Something went wrong! Please try again." 
     render :new 
    end 
    end 
end 

def edit 
    @user = User.find(params[:id]) 
end 

def update 
    @user = User.find(params[:id]) 
    if @user.is_admin? 
    if params[:user][:organization][:name].blank? && params[:user][:organization][:name] != @user.organization.name 
     params[:user][:organization][:name] = @user.organization.name 
    end 
    if params[:user][:organization][:access_code].blank? && params[:user][:organization][:access_code] != @user.organization.access_code 
     params[:user][:organization][:access_code] = @user.organization.access_code 
    end 
    @organization = Organization.find(params[:user][:organization_id]) 
    @organization.name = params[:user][:organization][:name] 
    @organization.access_code = params[:user][:organization][:access_code] 
    @organization.save 
    end 
    if @user.update(user_params) 
    flash[:success] = "Your settings have been updated!" 
    redirect_to edit_admin_user_path(@user.id) 
    else 
    flash.now[:error] = "Something went wrong! Please try again." 
    render :edit 
    end 
end 

private 
    def user_params 
    params.require(:user).permit(:organization_id, :email, :password, :password_confirmation, :full_name, :remember_me, {:organization_attributes => [:name, :website, :description, :access_code]}) 
    end 

users.rb的

class User < ActiveRecord::Base 
    authenticates_with_sorcery! 

    belongs_to :organization 

    VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][a-z\d\-.]+\.[a-z]+\z/i 

    validates_presence_of :full_name 
    validates_presence_of :email 
    validates_uniqueness_of :email, :on => :create 
    validates_format_of :email, :with => VALID_EMAIL_REGEX, :on => :create 
    validates_presence_of :password, :on => :create 
    validates_confirmation_of :password 
end 

organization.rb

class Organization < ActiveRecord::Base 
    authenticates_with_sorcery! 

    has_many :users, :dependent => :destroy 

    accepts_nested_attributes_for :users 

    validates_presence_of :name 
end 

new.html.erb

<% provide(:title, 'Create a User') %> 

<h1>Create a User</h1> 
<p>Use the form below to create an account.</p> 
<%= nested_form_for([:admin, @user], html: {role: "form"}) do |f| %> 
    <%= render "shared/error_messages", obj: @user %> 
    <fieldset> 
    <legend>User Information</legend> 
    <div class="form-group"> 
     <%= f.label :full_name, "Full Name" %> 
     <span class="help-block">How should others see you?</span> 
     <%= f.text_field :full_name, class: "form-control" %> 
    </div> 
    <div class="form-group"> 
     <%= f.label :email %> 
     <span class="help-block">Your email address is used as your login.</span> 
     <%= f.text_field :email, class: "form-control" %> 
    </div> 
    <div class="form-group"> 
     <%= f.label :password %> 
     <%= f.password_field :password, class: "form-control" %> 
    </div> 
    <div class="form-group"> 
     <%= f.label :password_confirmation, "Confirm Password" %> 
     <%= f.password_field :password_confirmation, class: "form-control" %> 
    </div> 
    </fieldset> 
    <%= f.fields_for :organization do |o| %> 
    <fieldset> 
     <legend>Associated Organization</legend> 
     <div class="form-group"> 
     <%= o.label :name, "Organization Name" %> 
     <span class="help-block">This is the name of the organization you are a part of.</span> 
     <%= o.text_field :name, class: "form-control" %> 
     </div> 
     <div class="form-group"> 
     <%= o.label :access_code, "Organization Access Code" %> 
     <span class="help-block">Leaving this field blank will setup a new organization.</span> 
     <%= 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, class: "text-btn" %> 
    </div> 
<% end %> 

edit.html.erb

<% provide(:title, "Edit User: #{@user.full_name} (#{@user.organization.name})") %> 

<h1>Edit User: <%= @user.full_name %> (<%= @user.organization.name %>)</h1> 
<p>Use the form below to manage your account.</p> 
<%= nested_form_for([:admin, @user], html: {role: "form"}) do |f| %> 
    <%= render "shared/error_messages", obj: @user %> 
    <fieldset> 
    <legend>User Information</legend> 
    <div class="form-group"> 
     <%= f.label :full_name, "Full Name" %> 
     <span class="help-block">How should others see you?</span> 
     <%= f.text_field :full_name, class: "form-control" %> 
    </div> 
    <div class="form-group"> 
     <%= f.label :email %> 
     <span class="help-block">Your email address is used as your login.</span> 
     <%= f.text_field :email, class: "form-control" %> 
    </div> 
    <div class="form-group"> 
     <%= f.label :password %> 
     <%= f.password_field :password, placeholder: "leave blank to keep password unchanged", class: "form-control" %> 
    </div> 
    <div class="form-group"> 
     <%= f.label :password_confirmation, "Confirm Password" %> 
     <%= f.password_field :password_confirmation, class: "form-control" %> 
    </div> 
    </fieldset> 
    <% if @user.is_admin? %> 
    <%= f.fields_for :organization do |o| %> 
     <fieldset> 
     <legend>Associated Organization</legend> 
     <div class="form-group"> 
      <%= o.label :name, "Organization Name" %> 
      <span class="help-block">This is the name of the organization you are a part of.</span> 
      <%= o.text_field :name, class: "form-control", value: @user.organization.name %> 
     </div> 
     <div class="form-group"> 
      <%= o.label :access_code, "Organization Access Code" %> 
      <span class="help-block">Leaving this field blank will setup a new organization.</span> 
      <%= o.text_field :access_code, class: "form-control", value: @user.organization.access_code %> 
     </div> 
     </fieldset> 
    <% end %> 
    <%= f.hidden_field :organization_id %> 
    <% end %> 
    <div class="form-actions"> 
    <%= f.submit "Update User", class: "btn btn-primary" %> 
    <%= link_to "Cancel", :back, class: "text-btn" %> 
    </div> 
<% end %> 

好吧,這些都是使它發生的所有文件。現在,我的應用程序已經完成了我所需要的幾乎所有事情,但這並不像生產級別的代碼。

我知道我遇到的一個問題是,如果用戶在組織字段中鍵入某些內容,而沒有其他控制器將創建並保存該組織,然後使用用戶驗證錯誤呈現表單。如果用戶模型中存在驗證錯誤,我不希望它保存組織。

我真的只是在尋求建議,如果有更好的方式做我想做的事情。如果你不能確切地告訴我要用這個代碼做什麼,或者有任何問題,請告訴我!

回答