2012-05-13 18 views
24

Nếu tôi cố gắng thực hiện đoạn mã sau:ActiveModel :: MassAssignmentSecurity :: Lỗi: Không thể hàng loạt assign bảo vệ thuộc tính

hassle = rota.hassles.create(:sender => user1, :receiver => user2, :type => "sms") 

tôi obain các lỗi sau:

Failure/Error: hassle = rota.hassles.create(:sender => user1, :receiver => user2, :type => "sms") 
ActiveModel::MassAssignmentSecurity::Error: 
    Can't mass-assign protected attributes: type 

Tôi Không chắc điều này có nghĩa là gì. Tôi đã làm cho: loại là bắt buộc, vì vậy nếu tôi loại bỏ nó, tôi nhận được một lỗi sql.

+3

"Loại" cột được sử dụng bởi mặc định bằng đường ray cho STI. Giải pháp tốt nhất là đổi tên cột kiểu thành cái gì khác. Cách giải quyết không được đề xuất là thêm vào tệp mô hình của bạn self.inheritance_column =: some_other_column_that_might_not_exists – bcd

+0

Có - xem thông tin này để biết thông tin về vấn đề STI sử dụng cột 'loại': http://stackoverflow.com/questions/7134559/rails-use-type-column-without-sti (mặc dù một tùy chọn tốt hơn có thể là thay đổi tên của cột). –

+0

vâng - Tôi đã gặp sự cố này. Đã thay đổi tên cột. thnks! – Karan

Trả lời

59

Một vài điều:

Khối lượng chuyển nhượng thường có nghĩa là đi qua các thuộc tính vào cuộc gọi tạo ra một đối tượng như là một phần của một thuộc tính băm. Tức là, bạn chuyển một loạt các thuộc tính trong một băm vào cuộc gọi tạo đối tượng mới. Ví dụ:

@user = User.create({:name => "My name", :user_type => "nice_user"}) 

Tuy nhiên, Rails bao gồm một số quy tắc bảo mật cơ bản có nghĩa là không phải tất cả các thuộc tính có thể được gán cách mà theo mặc định. Bạn phải xác định cái nào có thể trước. Bạn làm như vậy như thế này:

class User < ActiveRecord::Base 
    attr_accessible :name, :user_type 
end 

Nếu bạn không chỉ định một thuộc tính là attr_accessible, và bạn vượt qua nó để tạo ra các đối tượng, bạn nhận được lỗi bạn được đăng.

Dưới đây là chi tiết:

http://api.rubyonrails.org/v3.2.9/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html

Cách khác là để thiết lập một số thuộc tính khi bạn lần đầu tiên tạo ra các kỷ lục, và thiết lập khác sau - như vậy:

# In this example `user_type` is not attr_accessible so it needs to be set specifically 
@user = User.create({:name => "My name"}) 
@user.user_type = "nice_user" 
@user.save 

Ngoài ra, nếu bạn gặp sự cố khi sử dụng tên cột type vì đường ray bị nhầm lẫn và cho rằng bạn muốn sử dụng Thừa kế bảng đơn (STI), hãy kiểm tra câu trả lời cho câu hỏi này để xem cách thực hiện: http://guides.rubyonrails.org/

+0

cảm ơn ... đã hoạt động hoàn hảo! –

+0

nếu bạn cố gắng tạo bố mẹ có nhiều con cùng một lúc thì sao? ví dụ; 'Post.create (comments)' – tokhi

0

Here là một số thông tin về nhiệm vụ đại chúng trong Rails là gì và tại sao việc bảo vệ được thực hiện. Nó khá dễ dàng để có được xung quanh khi bạn thực sự muốn chỉ định một thuộc tính được bảo vệ, nhưng phải mất một vài dòng thêm.

hassle = rota.hassles.build(:sender => user1, :receiver => user2) 
hassle.type = 'sms' 
hassle.save 
+0

hassle.type = 'sms' có lẽ sẽ nâng cao một lớp Sms không tồn tại ngoại lệ – bcd

+0

Có lẽ. Tôi đang làm việc với giả thiết rằng OP biết anh ta đang làm gì với STI. – x1a4

7

Bạn có đang làm việc với Rails 3.2 trong khi thực hiện theo hướng dẫn 3.1 như bản phát hành thứ 4 "Phát triển Web nhanh với Rails" của Pragmatic Programmer không? Sau đó kiểm tra http://guides.rubyonrails.org/3_2_release_notes.html.

Vấn đề của bạn là từ Rails 3.1 đến 3.2 kiểm tra bảo vệ gán khối cho các mô hình Active Record được đặt thành 'nghiêm ngặt' theo mặc định. Nhận xét các dòng thích hợp trong các tệp này:

config/environments/development.rb 
config/environments/test.rb 

... và bạn tốt để tiếp tục tìm hiểu.Ghi rời này có hiệu lực khi mã hóa ứng dụng của bạn đầu tiên sản xuất :)

+0

"Bạn đang làm việc với Rails 3.2 trong khi làm theo hướng dẫn 3.1 chẳng hạn như bản phát hành thứ 4" Agile Web Development with Rails "của Pragmatic Programmer? Đó chính xác là những gì tôi đang làm. 1 để khắc phục sự cố của tôi. –

+0

Điều này khắc phục được sự cố của tôi, tôi đã nhận xét ra dòng này: 'config.active_record.mass_assignment_sanitizer =: strict' – mrzmyr

5
  1. Vui lòng thử: mở config/application.rb

  2. Xác định vị trí dòng config.active_record.whitelist_attributes = true

  3. Thay đổi đúng với sai

Sau đó, bạn sẽ ổn thôi.

PS: nhớ khởi động lại bảng điều khiển đường ray.

2

Bạn sẽ nhận được một lỗi khác, như thế này: cột 'loại' được dành riêng để lưu trữ lớp trong trường hợp thừa kế. Vì cột 'loại' không nên được sử dụng trong cơ sở dữ liệu bản ghi hoạt động.

0

Tôi không sử dụng whitelist_attributes vì trường hợp sử dụng khi tôi muốn cho phép gán hàng loạt cho logic nội bộ của tôi và thường không trực tiếp trong Bộ điều khiển cho các hành động CRUD. Tôi đề nghị sử dụng thông số mạnh trong những trường hợp đó. Nhưng khi bạn muốn kích hoạt hàng loạt nhiệm vụ cho mô hình cụ thể mà bạn làm

class Foo < ActiveRecord::Base 
    # disables mass-assigment 
    attr_protected 
end 

này về cơ bản đặt attr_protected để mảng rỗng ([])

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