Nhiều người trên chủ đề này và trên google giải thích rất rõ rằng attr_accessible
chỉ định danh sách trắng các thuộc tính được phép cập nhật hàng loạt ( tất cả các thuộc tính của một mô hình đối tượng cùng một lúc ) Điều này chủ yếu (và duy nhất) để bảo vệ ứng dụng của bạn từ "phân công hàng loạt" khai thác hải tặc.
Điều này được giải thích ở đây trên tài liệu Rails chính thức: Bài tập lớn
attr_accessor
là một mã ruby để (nhanh chóng) tạo các phương thức setter và getter trong Class. Đó là tất cả.
Bây giờ, điều còn thiếu như một lời giải thích là khi bạn tạo bằng cách nào đó một liên kết giữa mô hình (Rails) với bảng cơ sở dữ liệu, bạn KHÔNG BAO GIỜ, KHÔNG BAO GIỜ, KHÔNG BAO GIỜ, KHÔNG BAO GIỜ attr_accessor
trong mô hình của mình để tạo setters và getters để có thể sửa đổi bảng ghi chép.
Điều này là do mô hình của bạn kế thừa tất cả các phương thức từ ActiveRecord::Base
Lớp, đã xác định các trình truy cập CRUD cơ bản (Tạo, Đọc, Cập nhật, Xóa) cho bạn. Điều này được giải thích trên tài liệu chính thức ở đây Rails Model và tại đây Ghi đè bộ truy cập mặc định (cuộn xuống chương "Ghi đè bộ truy cập mặc định")
Ví dụ: chúng tôi có một bảng cơ sở dữ liệu gọi là "người dùng" chứa ba cột "tên đầu tiên", "tên cuối" và "vai trò":
Hướng dẫn SQL:
CREATE TABLE users (
firstname string,
lastname string
role string
);
Tôi giả sử rằng bạn đặt tùy chọn config.active_record.whitelist_attributes = true
trong cấu hình / môi trường / sản xuất.rb của bạn để bảo vệ ứng dụng của bạn khỏi khai thác phân công hàng loạt. Điều này được giải thích ở đây: Bài tập lớn
Mô hình Rails của bạn sẽ hoạt động hoàn hảo với Mô hình ở đây bên dưới:
class User < ActiveRecord::Base
end
Tuy nhiên, bạn sẽ cần cập nhật riêng từng thuộc tính của người dùng trong bộ điều khiển để Chế độ xem biểu mẫu của bạn hoạt động:
def update
@user = User.find_by_id(params[:id])
@user.firstname = params[:user][:firstname]
@user.lastname = params[:user][:lastname]
if @user.save
# Use of I18 internationalization t method for the flash message
flash[:success] = t('activerecord.successful.messages.updated', :model => User.model_name.human)
end
respond_with(@user)
end
Bây giờ để giảm bớt cuộc sống của bạn, bạn không muốn tạo một bộ điều khiển phức tạp cho mô hình Người dùng của mình. Vì vậy, bạn sẽ sử dụng attr_accessible
phương thức đặc biệt trong mô hình Lớp của mình:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
end
Vì vậy, bạn có thể sử dụng "đường cao tốc" (phân công hàng loạt) để cập nhật:
def update
@user = User.find_by_id(params[:id])
if @user.update_attributes(params[:user])
# Use of I18 internationlization t method for the flash message
flash[:success] = t('activerecord.successful.messages.updated', :model => User.model_name.human)
end
respond_with(@user)
end
Bạn đã không thêm các thuộc tính "vai trò" vào attr_accessible
danh sách vì bạn không để người dùng tự đặt vai trò của họ (như quản trị viên). Bạn tự làm điều này trên một View khác của quản trị viên đặc biệt.
Mặc dù chế độ xem người dùng của bạn không hiển thị trường "vai trò", một tên cướp biển có thể dễ dàng gửi yêu cầu POST HTTP bao gồm "vai trò" trong hàm băm params. Thuộc tính "vai trò" bị thiếu trên attr_accessible
là để bảo vệ ứng dụng của bạn khỏi đó.
Bạn vẫn có thể tự sửa đổi thuộc tính user.role của mình như bên dưới, nhưng không phải với tất cả các thuộc tính cùng nhau.
@user.role = DEFAULT_ROLE
Tại sao bạn sẽ sử dụng địa ngục attr_accessor
?
Chà, điều này sẽ xảy ra trong trường hợp biểu mẫu người dùng của bạn hiển thị một trường không tồn tại trong bảng người dùng của bạn dưới dạng cột.
Ví dụ: giả sử chế độ xem người dùng của bạn hiển thị trường "vui lòng cho biết quản trị viên rằng tôi đang ở đây". Bạn không muốn lưu trữ thông tin này trong bảng của bạn. Bạn chỉ muốn Rails gửi cho bạn một e-mail cảnh báo bạn rằng một người dùng "điên" ;-) đã đăng ký.
Để có thể sử dụng thông tin này, bạn cần lưu trữ tạm thời ở đâu đó. Điều gì dễ dàng hơn phục hồi nó trong một user.peekaboo
thuộc tính?
Vì vậy, bạn thêm trường này vào mô hình của bạn:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
attr_accessor :peekaboo
end
Vì vậy, bạn sẽ có thể sử dụng có giáo dục user.peekaboo
thuộc tính ở đâu đó trong bộ điều khiển của bạn để gửi e-mail hoặc làm bất cứ điều gì bạn muốn.
ActiveRecord sẽ không lưu thuộc tính "peekaboo" trong bảng của bạn khi bạn thực hiện user.save
vì cô ấy không thấy bất kỳ cột nào khớp với tên này trong mô hình của mình.
attr_accessor
được sử dụng để tạo các phương thức getter và setter. Vui lòng xem câu trả lời của tôi cho câu hỏi trước để được giải thích khá toàn diện vềattr_accessible
: stackoverflow.com/questions/2652907/ và sau đó cập nhật câu hỏi của bạn nếu bạn cần bất kỳ chi tiết cụ thể nào khác sau đó.