2013-06-27 27 views
201

Tôi có mô hình này trong Ruby nhưng nó ném một ActiveModel::ForbiddenAttributesErrorActiveModel :: ForbiddenAttributesError khi tạo người dùng mới

class User < ActiveRecord::Base 
    attr_accessor :password 
    validates :username, :presence => true, :uniqueness => true, :length => {:in => 3..20} 
    VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][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ể cho tôi biết cách loại bỏ lỗi này hoặc thiết lập biểu mẫu đăng ký người dùng thích hợp không?

+2

thử với việc thêm attr_accessible: mật khẩu,: password_confirmation ,: user_name,: email,: các thuộc tính khác của bạn trong Mô hình người dùng –

+0

Thêm * strong_parameter * gem để sử dụng * attr_accessible *. –

+0

thông số mạnh mẽ để sử dụng attr_accessible ?! –

Trả lời

364

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

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 
+1

Có bất kỳ tài liệu nào về lý do tại sao tính năng này hoạt động hoặc tại sao điều này là cần thiết? –

+16

@OmarJackman Chức năng được cung cấp bởi đá quý 'strong_parameter'. Nó được đề cập trong Rails Guides: http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters. – Domon

+20

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ử [AntonTrapps's] (https://github.com/ryanb/cancan/issues/835#issuecomment-18663815) giải pháp thay thế sạch sẽ cho đến khi CanCan được cập nhật. – mjnissim

3

Hoặc bạn có thể sử dụng Protected Attributes gem, tuy nhiên điều này đánh bại mục đích của yêu cầu params mạnh. Tuy nhiên, nếu bạn đang nâng cấp một ứng dụng cũ hơn, các 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ể tái cấu trúc attr_accessible thành các tham số mạnh.

62

Đố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ử AntonTrapps's khá sạch giải pháp workaround here 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ụ NoteController):

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

Cập nhật:

Đây là dự án tiếp tục cho CanC một gọi CanCanCan, trông đầy hứa hẹn:

CanCanCan

+0

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

16

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

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

Những cần phải được thiết lập cùng với những người 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ẽ gặp lỗi:

ActiveModel::ForbiddenAttributesError 
22

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

unlocked_params = ActiveSupport::HashWithIndifferentAccess.new(params) 

model.create!(unlocked_params) 

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

+0

Đây chính xác là những gì tôi cần. Cảm ơn! –

+0

Điều này cũng không hiệu quả đối với tôi, tôi quá bối rối ngay bây giờ ... –

-1

hello trong trường hợp lỗi của tôi là cố định nhưng nhận được kết quả trống là cơ sở dữ liệu.

def create 
@worklog = Worklog.new(user_params) 
@worklog.day = Date.today 
@worklog.week = Date.today.strftime("%W").to_i 
@worklog.author = User.current 
@worklog.save 
redirect_to worklogs_path() 
end 

def user_params 
params.require(:worklog).permit(:utf8, :authenticity_token, {:worklog => [:typee, :do, :todo, :feel, :plan_done, :plan, :week_feel, :score, :good, :nogood]}, :commit) 

}

Plugin gốc của tôi là https://github.com/IceskYsl/worklogs

6

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

Bạn sẽ nhận được lỗi này nếu CanCanCan không thể tìm thấy params đúng phương pháp.

Đối với hành động :create, Cancan sẽ cố gắng để khởi tạo một đối tượng mới với đầu vào làm vệ sinh bằng cách nhìn thấy nếu điều khiển của bạn sẽ đáp ứng với các phương pháp sau (theo thứ tự):

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

Ngoài ra, load_and_authorize_resource bây giờ có thể chọn tùy chọn param_method để chỉ định 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ể kết hợp các tùy chọn param_method với một biểu tượng tương ứng với tên của một phương pháp mà 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#strong-parameters

Các vấn đề liên quan