简体   繁体   English

使用 Ruby On Rails 的多个用户模型,并设计为具有单独的注册但一个共同的登录

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

i have same problem just like this link:我有同样的问题,就像这个链接:

Multiple user models with Ruby On Rails and devise to have separate registration routes but one common login route 使用 Ruby On Rails 的多个用户模型,并设计为具有单独的注册路径但有一个通用的登录路径

in my app there are two model在我的应用程序中有两个模型

  1. Company公司

  2. Employee员工

my User model我的用户模型

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

my Company model我的公司模式

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

my Employee model我的员工模型

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

app/views/devise/registrations/new.html.erb应用程序/视图/设计/注册/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" %>

my registration create method :我的注册创建方法:

controllers/users/registrations_controller.rb控制器/用户/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

my application helper file :我的应用程序帮助文件:

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

but i got error something like this when i open any user sign_up page:但是当我打开任何用户注册页面时,我遇到了这样的错误:

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

localhost:3000/companies/sign_up

error in registration view注册视图中的错误

ERROR :-错误 :-

在此处输入图片说明

So what am I doing wrong?那么我做错了什么?

Your question is really broad but to solve the error you posted, it is erroring undefined method because of the nested hash that doesn't exist.您的问题非常广泛,但为了解决您发布的错误,由于不存在的嵌套散列,它正在错误未定义的方法。 Here's the example:这是示例:

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

If your code is to expect that params[:user] won't ever exist without a user_type and you want to default that to company, then that would simply be:如果您的代码期望 params[:user] 在没有user_type情况下永远不会存在,并且您希望将其默认为 company,那么这将是:

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

Alternativley if you want to just return a string if params[:user] doesn't exist, you can use ||= or Hash#fetch with a default value.或者,如果您只想在 params[:user] 不存在的情况下返回一个字符串,您可以使用 ||= 或Hash#fetch与默认值。 Hash#fetch is a safer way to error handle imo. Hash#fetch 是一种更安全的错误处理方式。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 Ruby On Rails 的多个用户模型,并设计为具有单独的注册路径但有一个通用的登录路径 - Multiple user models with Ruby On Rails and devise to have separate registration routes but one common login route 为Ruby on Rails上的Devise设置不同的用户模型和注册路径 - Setting up different User models and registration paths for Devise on Ruby on Rails Ruby on Rails发送关于设备注册和登录的参数 - Ruby on Rails send params on devise registration and login 使用Devise登录的多个模型? - Multiple Models for one login with Devise? Rails 4中多个Devise登录模块的通用登录 - Common Login for multiple Devise Login Modules in Rails 4 Rails5和Devise:多个模型的登录表单 - Rails5 and Devise: Login form for multiple models Ruby on Rails Devise登录必须登录两次 - Ruby on Rails Devise login have to sign in twice Ruby on Rails:如何为一个表和多个模型使用多个控制器 - Ruby on Rails: How to have multiple controllers for one table AND multiple models Ruby on Rails:设计-将用户控制器与设计分开是否不好? - Ruby on Rails: Devise - Is it bad to have a Users Controller separate from devise? Rails:如何让设计中的两个用户模型通过注册 - Rails: how to let two user models in devise go through registration
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM