หลายคนในชุดข้อความนี้และบน google อธิบายได้ดีมากซึ่งattr_accessible
ระบุรายการที่อนุญาตของแอตทริบิวต์ที่ได้รับอนุญาตให้อัปเดตเป็นกลุ่ม ( คุณลักษณะทั้งหมดของรูปแบบวัตถุพร้อมกันในเวลาเดียวกัน ) เป็นส่วนใหญ่ (และเท่านั้น) เพื่อปกป้องแอปพลิเคชันของคุณ จากการใช้ประโยชน์จากโจรสลัด "การมอบหมายจำนวนมาก"
นี่คือคำอธิบายที่นี่ในเอกสารทางรถไฟอย่างเป็นทางการ: การมอบหมายจำนวนมาก
attr_accessor
เป็นรหัสทับทิมเพื่อ (อย่างรวดเร็ว) สร้างเมธอดและทะเยอทะยานในคลาส นั่นคือทั้งหมดที่
ตอนนี้สิ่งที่ขาดหายไปตามคำอธิบายก็คือเมื่อคุณสร้างลิงก์ระหว่างโมเดล (Rails) กับตารางฐานข้อมูลคุณไม่จำเป็นไม่จำเป็นต้องใช้attr_accessor
โมเดลของคุณในการสร้าง setters และ getters เพื่อที่จะสามารถปรับเปลี่ยน บันทึกของตาราง
นี่เป็นเพราะโมเดลของคุณสืบทอดวิธีการทั้งหมดจากActiveRecord::Base
Class ซึ่งกำหนด accessors CRUD พื้นฐาน (สร้าง, อ่าน, อัปเดต, ลบ) ให้คุณแล้ว นี่คือคำอธิบายในเอกสารอย่างเป็นทางการที่นี่Rails Modelและที่นี่การเขียนทับค่าเริ่มต้น accessor (เลื่อนลงไปที่บท "Overwrite default accessor")
พูดเช่น: เรามีตารางฐานข้อมูลชื่อ "ผู้ใช้" ที่มีสามคอลัมน์ "ชื่อ", "นามสกุล" และ "บทบาท":
คำแนะนำ SQL:
CREATE TABLE users (
firstname string,
lastname string
role string
);
ฉันสันนิษฐานว่าคุณตั้งค่าตัวเลือกconfig.active_record.whitelist_attributes = true
ใน config / environment / production.rb เพื่อป้องกันแอปพลิเคชันของคุณจากการใช้ประโยชน์จากการมอบหมายจำนวนมาก นี่คือคำอธิบายที่นี่: การมอบหมายจำนวนมาก
โมเดล Rails ของคุณจะทำงานกับ Model ได้อย่างสมบูรณ์ด้านล่าง:
class User < ActiveRecord::Base
end
อย่างไรก็ตามคุณจะต้องอัปเดตแต่ละแอตทริบิวต์ของผู้ใช้แยกต่างหากในคอนโทรลเลอร์ของคุณเพื่อให้มุมมองฟอร์มของคุณทำงาน:
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
ตอนนี้เพื่อความสะดวกในชีวิตของคุณคุณไม่ต้องการให้ตัวควบคุมที่ซับซ้อนสำหรับรูปแบบผู้ใช้ของคุณ ดังนั้นคุณจะใช้attr_accessible
วิธีพิเศษในรุ่น Class ของคุณ:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
end
ดังนั้นคุณสามารถใช้ "ทางหลวง" (การกำหนดจำนวนมาก) เพื่ออัปเดต:
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
คุณไม่ได้เพิ่มแอททริบิวต์ "บทบาท" ลงในattr_accessible
รายการเนื่องจากคุณจะไม่ให้ผู้ใช้กำหนดบทบาทของตนเอง (เช่นผู้ดูแลระบบ) คุณทำสิ่งนี้ด้วยตัวคุณเองบนมุมมองผู้ดูแลระบบพิเศษอื่น
แม้ว่ามุมมองผู้ใช้ของคุณจะไม่แสดงฟิลด์ "บทบาท" แต่โจรสลัดอาจส่งคำขอ HTTP POST ที่รวมถึง "บทบาท" ในแฮช params ได้อย่างง่ายดาย แอตทริบิวต์ "role" ที่หายไปattr_accessible
คือการปกป้องแอปพลิเคชันของคุณ
คุณยังคงสามารถแก้ไขแอตทริบิวต์ user.role ของคุณเองได้เหมือนด้านล่าง แต่ไม่สามารถใช้ร่วมกับแอตทริบิวต์ทั้งหมดได้
@user.role = DEFAULT_ROLE
ทำไมนรกคุณจะใช้attr_accessor
?
ในกรณีนี้ผู้ใช้ของคุณจะแสดงเขตข้อมูลที่ไม่มีอยู่ในตารางผู้ใช้ของคุณเป็นคอลัมน์
ตัวอย่างเช่นสมมติว่ามุมมองผู้ใช้ของคุณแสดงฟิลด์ "Please-tell-the-admin-that-I'm-in-here" คุณไม่ต้องการจัดเก็บข้อมูลนี้ในตารางของคุณ คุณเพียงแค่ต้องการให้ Rails ส่งอีเมลเตือนคุณว่ามีผู้ใช้ "คนบ้า" ;-) สมัครรับข้อมูล
เพื่อให้สามารถใช้ประโยชน์จากข้อมูลนี้ได้คุณจะต้องเก็บมันไว้ชั่วคราว อะไรจะง่ายไปกว่าการกู้คืนในuser.peekaboo
แอตทริบิวต์
ดังนั้นคุณเพิ่มฟิลด์นี้ในโมเดลของคุณ:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
attr_accessor :peekaboo
end
ดังนั้นคุณจะสามารถใช้user.peekaboo
คุณสมบัติที่มีการศึกษาเพื่อควบคุมการส่งอีเมลหรือทำสิ่งที่คุณต้องการ
ActiveRecord จะไม่บันทึกแอตทริบิวต์ "peekaboo" ในตารางของคุณเมื่อคุณทำuser.save
เพราะเธอไม่เห็นคอลัมน์ใด ๆ ที่ตรงกับชื่อนี้ในรูปแบบของเธอ
attr_accessor
ใช้ในการสร้างวิธีการทะเยอทะยานและ Setter โปรดดูคำตอบของฉันสำหรับคำถามก่อนหน้านี้สำหรับคำอธิบายที่ครอบคลุมมากของattr_accessible
: stackoverflow.com/questions/2652907/ …จากนั้นอัปเดตคำถามของคุณหากคุณต้องการรายละเอียดเฉพาะอื่น ๆ หลังจากนั้น