ActiveModel :: ForbiddenAttributError khi tạo người dùng mới


223

Tôi có mô hình này trong Ruby nhưng nó ném ActiveModel::ForbiddenAttributesError

class User < ActiveRecord::Base
  attr_accessor :password
  validates :username, :presence => true, :uniqueness => true, :length => {:in => 3..20}
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, :uniqueness => true, format: { with: VALID_EMAIL_REGEX }

  validates :password, :confirmation => true
  validates_length_of :password, :in => 6..20, :on => :create

  before_save :encrypt_password
  after_save :clear_password

  def encrypt_password
    if password.present?
      self.salt = BCrypt::Engine.generate_salt
      self.encrypted_password= BCrypt::Engine.hash_secret(password, salt)
    end
  end

  def clear_password
    self.password = nil
  end
end

khi tôi chạy hành động này

  def create
    @user = User.new(params[:user])
    if @user.save
      flash[:notice] = "You Signed up successfully"
      flash[:color]= "valid"
    else
      flash[:notice] = "Form is invalid"
      flash[:color]= "invalid"
    end
    render "new"
  end

trên ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux].

Bạn có thể vui lòng cho tôi biết làm thế nào để thoát khỏi lỗi này hoặc thiết lập một biểu mẫu đăng ký người dùng phù hợp?


2
thử với việc thêm attr_accessible: password ,: password_ thông tin xác nhận ,: user_name ,: email ,: thuộc tính của bạn trong mô hình Người dùng
Bachan Smruty

1
Thêm đá quý strong_parameter để sử dụng attr_accessible .
Ôn Minh Li

tham số mạnh để sử dụng attr_accessible?!
Thiem Nguyễn

1
Tôi tin rằng @BruceLi có nghĩa là: Thêm protected_attributesđá quý để sử dụng attr_accessible.
Stefan Magnuson

Câu trả lời:


398

Tôi đoán bạn đang sử dụng Rails 4. Nếu vậy, các tham số cần thiết phải được đánh dấu theo yêu cầu.

Bạn có thể muốn làm điều đó như thế này:

class UsersController < ApplicationController

  def create
    @user = User.new(user_params)
    # ...
  end

  private

  def user_params
    params.require(:user).permit(:username, :email, :password, :salt, :encrypted_password)
  end
end

2
Có tài liệu nào về lý do tại sao điều này hoạt động hoặc tại sao điều này là cần thiết?
DiverseAndRemote.com

20
@OmarJackman Chức năng được cung cấp bởi strong_parameterđá quý. Nó được trình bày trong Hướng dẫn Rails: guide.rubyonrails.org/ .
Domon

21
Mọi người có thể gặp phải điều này nếu họ sử dụng CanCan với Rails 4.0. Hãy thử giải pháp khắc phục khá sạch của AntonTrapps cho đến khi CanCan được cập nhật.
mjnissim

@mjnissim Bạn có vui lòng gửi bài này dưới dạng câu trả lời riêng không? Tôi đã bỏ lỡ nó lần đầu tiên, nhưng nó vẫn giúp tôi tiết kiệm rất nhiều thời gian.
Paul Pettengill

64

Đối với những người sử dụng CanCan . Mọi người có thể gặp phải điều này nếu họ sử dụng CanCan với Rails 4+ . Hãy thử giải pháp khắc phục khá sạch của AntonTrapps tại đây cho đến khi CanCan được cập nhật:

Trong ApplicationController:

before_filter do
  resource = controller_name.singularize.to_sym
  method = "#{resource}_params"
  params[resource] &&= send(method) if respond_to?(method, true)
end

và trong bộ điều khiển tài nguyên (ví dụ NoteContoder):

private
def note_params
  params.require(:note).permit(:what, :ever)
end

Cập nhật:

Đây là một dự án tiếp tục cho CanCan được gọi là CanCanCan , có vẻ đầy hứa hẹn:

CanCanCan


1
Cảm ơn!! Tôi có một câu hỏi, với CanCanCan (hoạt động) đã được giải quyết hay không cần mã này?
Adriano gửi lại

Đối với tôi, CanCanCan vẫn có vấn đề. Không sử dụng load_resourcehoặc sử dụng load_resource :except => :creategiải quyết vấn đề. Kiểm tra câu trả lời ban đầu tại đây
Tun

24

Có một cách dễ dàng hơn để tránh các Thông số mạnh, bạn chỉ cần chuyển đổi các tham số thành hàm băm thông thường, như:

unlocked_params = ActiveSupport::HashWithIndifferentAccess.new(params)

model.create!(unlocked_params)

Điều này đánh bại mục đích của các tham số mạnh tất nhiên, nhưng nếu bạn ở trong tình huống như của tôi (tôi đang tự quản lý các thông số được phép trong một phần khác của hệ thống của mình) thì điều này sẽ hoàn thành công việc.


Không hoạt động trong rails 6, ngoại lệ:unable to convert unpermitted parameters to hash
Tyler

20

Nếu sử dụng ActiveAdmin, đừng quên rằng cũng có một allow_params trong khối đăng ký mô hình:

ActiveAdmin.register Api::V1::Person do
  permit_params :name, :address, :etc
end

Chúng cần được đặt cùng với những thứ trong bộ điều khiển:

def api_v1_person_params
  params.require(:api_v1_person).permit(:name, :address, :etc)
end

Nếu không, bạn sẽ nhận được lỗi:

ActiveModel::ForbiddenAttributesError

18

Đối với những người sử dụng CanCanCan :

Bạn sẽ gặp lỗi này nếu CanCanCan không thể tìm đúng phương thức params .

Đối với :createhành động, CanCan sẽ cố gắng khởi tạo một thể hiện mới với đầu vào được khử trùng bằng cách xem liệu bộ điều khiển của bạn có đáp ứng với các phương thức sau (theo thứ tự):

  1. create_params
  2. <model_name>_params chẳng hạn như article_params (đây là quy ước mặc định trong đường ray để đặt tên phương thức param của bạn)
  3. resource_params (một phương thức được đặt tên chung mà bạn có thể chỉ định trong mỗi bộ điều khiển)

Ngoài ra, load_and_authorize_resourcebây giờ có thể có một param_methodtùy chọn để chỉ định một phương thức tùy chỉnh trong bộ điều khiển để chạy để vệ sinh đầu vào.

Bạn có thể liên kết param_methodtùy chọn với một biểu tượng tương ứng với tên của một phương thức sẽ được gọi là:

class ArticlesController < ApplicationController
  load_and_authorize_resource param_method: :my_sanitizer

  def create
    if @article.save
      # hurray
    else
      render :new
    end
  end

  private

  def my_sanitizer
    params.require(:article).permit(:name)
  end
end

nguồn: https://github.com/CanCanCommunity/cancancan#33-strong-parameter


3

Ngoài ra, bạn có thể sử dụng đá quý được bảo vệ , tuy nhiên điều này đánh bại mục đích yêu cầu các thông số mạnh. Tuy nhiên, nếu bạn đang nâng cấp một ứng dụng cũ hơn, Thuộc tính được bảo vệ sẽ cung cấp một lộ trình dễ dàng để nâng cấp cho đến khi bạn có thể cấu trúc lại attr_accessable thành các thông số mạnh.


0

Nếu bạn đang sử dụng Rails 4 và bạn gặp lỗi này, điều đó có thể xảy ra nếu bạn đang sử dụng enumtrên mô hình nếu bạn đã xác định bằng các ký hiệu như thế này:

class User
  enum preferred_phone: [:home_phone, :mobile_phone, :work_phone]
end

Biểu mẫu sẽ vượt qua nói bộ chọn radio dưới dạng tham số chuỗi. Đó là những gì đã xảy ra trong trường hợp của tôi. Cách khắc phục đơn giản là thay đổi enumthành chuỗi thay vì ký hiệu

enum preferred_phone: %w[home_phone mobile_phone work_phone]
# or more verbose
enum preferred_phone: ['home_phone', 'mobile_phone', 'work_phone']
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.