簡體   English   中英

使用 Ruby On Rails 的多個用戶模型,並設計為具有單獨的注冊但一個共同的登錄

[英]Multiple user models with Ruby On Rails and devise to have separate registration but one common login

我有同樣的問題,就像這個鏈接:

使用 Ruby On Rails 的多個用戶模型,並設計為具有單獨的注冊路徑但有一個通用的登錄路徑

在我的應用程序中有兩個模型

  1. 公司

  2. 員工

我的用戶模型

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

  belongs_to :usr, :polymorphic => true
end

我的公司模式

class Company < ActiveRecord::Base
  has_many :users, :as => :usr
end

我的員工模型

class Employee < ActiveRecord::Base
  has_many :users, :as => :usr
end

應用程序/視圖/設計/注冊/new.html.erb

<h2>Sign up</h2>

<%
  # customized code begin

  params[:user][:user_type] ||= 'company'

  if ["company", "employee"].include? params[:user][:user_type].downcase
    child_class_name = params[:user][:user_type].downcase.camelize
    user_type = params[:user][:user_type].downcase
  else
    child_class_name = "Company"
    user_type = "company"
  end

  resource.usr = child_class_name.constantize.new if resource.usr.nil?

  # customized code end
%>



<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= devise_error_messages! %>

  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true %>
  </div>

  <div class="field">
    <%= f.label :password %>
    <% if @validatable %>
    <em>(<%= @minimum_password_length %> characters minimum)</em>
    <% end %><br />
    <%= f.password_field :password, autocomplete: "off" %>
  </div>

  <div class="field">
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation, autocomplete: "off" %>
  </div>


  <% # customized code begin %>
  <%= fields_for resource.usr do |rf| %>
    <% render :partial => "#{child_class_name.underscore}_fields", :locals => { :f => rf } %>
  <% end %>

  <%= hidden_field :user, :user_type, :value => user_type %>
  <% # customized code end %>



  <div class="actions">
    <%= f.submit "Sign up" %>
  </div>
<% end %>

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

我的注冊創建方法:

控制器/用戶/registrations_controller.rb

class Users::RegistrationsController < Devise::RegistrationsController
 def create
    build_resource

    # customized code begin

    # crate a new child instance depending on the given user type
    child_class = params[:user][:user_type].camelize.constantize
    resource.usr = child_class.new(params[child_class.to_s.underscore.to_sym])

    # first check if child instance is valid
    # cause if so and the parent instance is valid as well
    # it's all being saved at once
    valid = resource.valid?
    valid = resource.usr.valid? && valid

    # customized code end

    if valid && resource.save    # customized code
      if resource.active_for_authentication?
        set_flash_message :notice, :signed_up if is_navigational_format?
        sign_in(resource_name, resource)
        respond_with resource, :location => redirect_location(resource_name, resource)
      else
        set_flash_message :notice, :inactive_signed_up, :reason => inactive_reason(resource) if is_navigational_format?
        expire_session_data_after_sign_in!
        respond_with resource, :location => after_inactive_sign_up_path_for(resource)
      end
    else
      clean_up_passwords(resource)
      respond_with_navigational(resource) { render :new }
    end
  end
end

我的應用程序幫助文件:

module ApplicationHelper
    def my_devise_error_messages!
    return "" if resource.errors.empty? && resource.usr.errors.empty?

    messages = usr_messages = ""

    if !resource.errors.empty?
      messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
    end

    if !resource.usr.errors.empty?
      usr_messages = resource.usr.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
    end

    messages = messages + usr_messages   
    sentence = I18n.t("errors.messages.not_saved",
                      :count => resource.errors.count + resource.usr.errors.count,
                      :resource => resource.class.model_name.human.downcase)

    html = <<-HTML
    <div id="error_explanation">
    <h2>#{sentence}</h2>
    <ul>#{messages}</ul>
    </div>
    HTML

    html.html_safe
  end
end

但是當我打開任何用戶注冊頁面時,我遇到了這樣的錯誤:

localhost:3000/emloyees/sign_up **OR**

localhost:3000/companies/sign_up

注冊視圖中的錯誤

錯誤 :-

在此處輸入圖片說明

那么我做錯了什么?

您的問題非常廣泛,但為了解決您發布的錯誤,由於不存在的嵌套散列,它正在錯誤未定義的方法。 這是示例:

[1] pry(main)> params = {}
=> {}
[2] pry(main)> params[:user]
=> nil
[3] pry(main)> params[:user][:user_type]
NoMethodError: undefined method `[]' for nil:NilClass

如果您的代碼期望 params[:user] 在沒有user_type情況下永遠不會存在,並且您希望將其默認為 company,那么這將是:

[7] pry(main)> params[:user] ||= { user_type: "company" }
=> {:user_type=>"company"}
[8] pry(main)> params
=> {:user=>{:user_type=>"company"}}

或者,如果您只想在 params[:user] 不存在的情況下返回一個字符串,您可以使用 ||= 或Hash#fetch與默認值。 Hash#fetch 是一種更安全的錯誤處理方式。

[5] pry(main)> params.fetch(:user, "company")
=> "company"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM