在RoR4中清除额外的strong_parameters

时间:2013-09-15 18:06:22

标签: ruby-on-rails ruby-on-rails-4 strong-parameters clearance

我正在使用清除宝石,这基本上是通过电子邮件进行身份验证。

现在我想通过电子邮件保留登录信息,但是想要添加一个名称'字段进入用户的注册表。

User.rb

class User < ActiveRecord::Base
  include Clearance::User

  validates_presence_of :name
  validates_uniqueness_of :name
end

users_controller.rb

class UsersController < Clearance::UsersController
  def create
    @user = user_from_params

    if @user.save(permit_params)
      sign_in @user
      render :json => {:success => true}
    else
      render :json => {:success => false}
    end
  end

  private

  def user_from_params
    user_params = params[:user] || Hash.new
    email = user_params.delete(:email)
    password = user_params.delete(:password)

    Clearance.configuration.user_model.new(user_params).tap do |user|
      user.email = email
      user.password = password
    end
  end

  def permit_params
    params.require(:user).permit(:name, :email, :encrypted_password, :password, :confirmation_token, :remember_token)
  end
end

正如您所看到的,我已将权限添加到.save,但仍然应用程序会根据请求向我发出以下错误:

ActiveModel::ForbiddenAttributesError in Clearance::UsersController#create

如果我从表单中删除:name文本字段,一切正常,但我想为表单添加其他字段。

4 个答案:

答案 0 :(得分:3)

您需要将 users_controller 放入以下文件夹中:

应用/控制器/间隙/ users_controller.rb

然后在 users_controller.rb 中,而不是:

class UsersController < Clearance::UsersController

你需要把:

class Clearance::UsersController < ApplicationController

这不会覆盖清除用户控制器。相反,现在你正在写它。这是您的注册表单将转到的控制器。因此,您仍需要包含Clearance的gem中的基本代码并进行编辑 的大减价:: UsersController#user_from_params

def user_from_params
  user_params = params[:user] || Hash.new
  email = user_params.delete(:email)
  password = user_params.delete(:password)
  name = user_params.delete(:name)

  Clearance.configuration.user_model.new(user_params).tap do |user|
    user.email = email
    user.password = password
    user.name = name
  end
end

并更新 Clearance :: UsersController#permit_params

def permit_params
  params.require(:user).permit(:name, :email, :password)
end

答案 1 :(得分:2)

更新:我已经改变了我以前的答案,因为它错过了重点。

您提供的代码很好。您获得ActiveModel::ForbiddenAttributesError的原因是因为您没有覆盖Clearance Users Controller。

您需要告诉您的应用使用覆盖控制器而不是Clearance引擎内的控制器,方法是在config / routes.rb中添加以下内容。

resources :users,
  controller: 'users',
  only: 'create'

IMO这比在上面的应用程序代码中编写新的Clearance::UsersController更好。

答案 2 :(得分:1)

我尝试了两种方式,并意识到你不需要许可证参数。你只需做4件事:

  • 在迁移中添加名称列
  • 创建 app / controllers / users_contoller.rb 以覆盖gem控制器
  • 创建新表单以接受名称 app / views / users / new.html.erb
  • 修改路线

从生成的迁移rails generate clearance:install开始(在运行rake db:migrate之前)

  1. 添加一个带有索引的name:string列,以便您的迁移如下所示: 通过添加此列,它包含在用户参数的创建中。

    def change
      change_table :users do |t|
        t.timestamps null: false
        t.string :email, null: false
        t.string :name, null: false, limit: 50
        t.string :encrypted_password, limit: 128, null: false
        t.string :confirmation_token, limit: 128
        t.string :remember_token, limit: 128, null: false
      end
    
      add_index :users, :name
      add_index :users, :email
      add_index :users, :remember_token
    end
    
  2. 然后你只需要创建2个文件:

    app / controllers / users_controller.rb

    class UsersController < Clearance::UsersController
    
      def create
        @user = user_from_params
    
        if @user.save
          sign_in @user
          redirect_to '/'
        else
          render template: 'users/new'
        end 
      end 
    
      private
    
      def user_from_params
        user_params = params[:user] || Hash.new
        name = user_params.delete(:name)
        email = user_params.delete(:email)
        password = user_params.delete(:password)
    
        Clearance.configuration.user_model.new(user_params).tap do |user|
          user.name = name
          user.email = email
          user.password = password
        end
      end
    end
    

    应用/视图/用户/ new.html.erb

    <div id='clearance' class='sign-up'>
      <h2><%= t('.title') %></h2>
    
      <%= form_for @user do |form| %>
      <div class='text-field'>
        <%= form.label :name %>
        <%= form.text_field :name, :type => 'name' %>
      </div>
    
      <div class='text-field'>
        <%= form.label :email %>
        <%= form.text_field :email, :type => 'email' %>
      </div>
    
      <div class='password-field'>
        <%= form.label :password %>
        <%= form.password_field :password %>
      </div>
    
      <div class='submit-field'>
        <%= form.submit %>
      </div>
    
      <div class='other-links'>
        <%= link_to t('.sign_in'), sign_in_path %>
      </div>
      <% end %>
    </div>
    

    然后你的路线应该包括这个

    resources :users,
        controller: 'users',
        only: 'create'
    

答案 3 :(得分:1)

您实际上并不需要重新实现create方法,以防万一您正在创建API(看起来像什么)。

步骤如下:

  • 配置/ routes.rb中

    Rails.application.routes.draw do
      resources :users, controller: 'users', only: Clearance.configuration.user_actions
    end
    
  • 应用程序/控制器/ users_controller.rb

    class UsersController < Clearance::UsersController
    
      private
    
      def user_from_params
        email = user_params.delete(:email)
        password = user_params.delete(:password)
        name = user_params.delete(:name)
    
        Clearance.configuration.user_model.new(user_params).tap do |user|
          user.email = email
          user.password = password
          user.name = name
        end
      end
    
    end
    

之后,将名称字段添加到表单中即可完成。