【问题标题】:How to create new devise user using foreign controller如何使用外部控制器创建新的设计用户
【发布时间】:2016-06-28 21:18:19
【问题描述】:

几个小时以来我一直在尝试这个,但没有成功,所以,终于向你们寻求帮助。

场景

我有两个设计模型,即学院和经理。他们都工作正常,但我想要实现的是学院应该能够创建或删除经理。为此,我创建了一个 Codashboard 控制器#view,它只有在 College 登录后才能访问。这个控制器#view 对有一个用于提交经理电子邮件和密码并提交到数据库的表单。

问题

每当我提交表单时,我都不会收到任何错误,但更改不会提交到数据库。

详情

从终端提取

Started POST "/codashboard" for 127.0.0.1 at 2016-03-14 04:59:41 +0530
Processing by CodashboardController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"P85GD7Wnt1RYNDgxxMxrSH6tUzW/PUBvqTXs8lYHY+HkvRXnq3s/IQL50SyMeDI1xXlalztTMbTZDNcPsXuckw==", "manager"=>{"email"=>"manager11@gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
   (0.1ms)  BEGIN
   (0.1ms)  ROLLBACK
Redirected to http://localhost:3000/codashboard
Completed 302 Found in 4ms (ActiveRecord: 0.3ms)

对应视图

<%= form_for @addmanager, url: {action: "create"} do |f| %>
    <div><%= f.label :email %><br />
    <%= f.email_field :email %></div>

    <div><%= f.label :password %><br />
    <%= f.password_field :password %></div>

    <div><%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation %></div>

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

对应的控制器

class CodashboardController < ApplicationController
  def index
    if college_signed_in?
        @managers = College.find_by_id(current_college.id).managers
        @addmanager = Manager.create(params[:addmanager])
    end
  end

  def new
    @addmanager = Manager.new
  end

  def create
    Manager.create(params[:addmanager])
    redirect_to codashboard_index_path
  end

  def addmanager
    @addmanager = Manager.new(:email => "manager8@gmail.com", :password => "qwertyuiop")
    @addmanager.save
    redirect_to codashboard_index_path
  end
end

注意:我尝试使用默认设计表单,但它总是在创建我不想要的新用户后登录。

注意 2:方法 addmanager 工作正常,并在调用时在数据库中添加一个条目。所以,我的模型没有问题。

请提出可能的问题

【问题讨论】:

    标签: ruby-on-rails database devise


    【解决方案1】:

    我强烈怀疑验证错误,您看不到任何错误,因为您在失败和成功验证中都进行了重定向,这里有两个选项:

    快速而肮脏的方式,将Manager.create更改为Manager.create!,如果验证失败,则会抛出错误。

    做得好,并在验证失败时重新呈现表单并显示错误消息:

    class CodashboardController < ApplicationController
    
      def create
        @addmanager = Manager.new(addmanager_params)
    
        if @addmanager.save
          redirect_to codashboard_index_path
        else
          render :new
        end
      end
    
      private
    
      def addmanager_params
        require(:addmanager).permit(:email, :password, :password_confirmation)
      end 
    end    
    

    我还添加了强参数以确保只能设置允许的属性。

    更新:

    真正的错误是,Rails 从传递给它的模型推断属性键(即@addmanager.class,即Manager),因此您在日志中的响应显示,它的键为“经理”:

    "manager"=>{"email"=>"manager11@gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}
    

    但您希望它被键入为“addmanager”,如下所示:

    "addmanager"=>{"email"=>"manager11@gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}
    

    要强制执行此操作,您可以使用 as: 选项将 form_for 表单构建器更改为使用别名:

    <%= form_for @addmanager, as: :addmanager, url: {action: "create"} do |f| %>
    

    【讨论】:

    • 这样做,结果:ActiveRecord::RecordInvalid in CodashboardController#create 验证失败:电子邮件不能为空,密码不能为空 def create Manager.create!(params[:addmanager] ) 重定向到 codashboard_index_path 结束
    • 好的,仔细检查一下你的日志,上面写着manager: { email: ...., password: ..., ....},但你希望它是addmanager: { email: ...., password: ...., ... }
    • 我猜不是,@addmanager 是用户定义的变量。 Manager 是我使用 devise 生成的模型
    • form_for 将从@addmanager.class 中推断出属性的键,即Manager
    • 我试过你说的,它给了我 CodashboardController#create 中的 ActiveModel::ForbiddenAttributesError
    【解决方案2】:

    我最近了解到,Devise 只是 AUTHENTICATION,但不包括 AUTHORIZATION。学院模型无权创建其他设计模型。我建议使用授权 gem,例如 CanCanCan

    希望有帮助!

    【讨论】:

    • 这不重要,因为他直接在控制器中的数据库模型上工作,它具有完全控制权。
    • 哦 - 我的印象是登录时您无法创建其他用户,并且由于两个模型都是设计,这将是限制。
    猜你喜欢
    • 1970-01-01
    • 2020-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多