Banyak orang di utas ini dan di Google menjelaskan dengan sangat baik yang attr_accessible
menentukan daftar putih atribut yang diizinkan untuk diperbarui secara massal ( semua atribut dari suatu model objek bersamaan pada saat yang sama ) Ini terutama (dan hanya) untuk melindungi aplikasi Anda dari eksploitasi bajak laut "penugasan massal".
Ini dijelaskan di sini di dokumen resmi Rails: Mass Assignment
attr_accessor
adalah kode ruby untuk (dengan cepat) membuat metode setter dan pengambil dalam suatu Class. Itu saja.
Sekarang, apa yang hilang sebagai penjelasan adalah bahwa ketika Anda membuat entah bagaimana tautan antara model (Rails) dengan tabel database, Anda TIDAK PERNAH, TIDAK PERNAH, TIDAK PERNAH perlu attr_accessor
dalam model Anda untuk membuat setter dan getter agar dapat memodifikasi Anda catatan tabel.
Ini karena model Anda mewarisi semua metode dari ActiveRecord::Base
Kelas, yang sudah mendefinisikan aksesor CRUD dasar (Buat, Baca, Perbarui, Hapus) untuk Anda. Ini dijelaskan pada dokumen resmi di sini Rails Model dan di sini Menimpa akseptor default (gulir ke bawah ke bab "Timpa accessor default")
Katakan misalnya bahwa: kami memiliki tabel database yang disebut "pengguna" yang berisi tiga kolom "nama depan", "nama belakang" dan "peran":
Instruksi SQL:
CREATE TABLE users (
firstname string,
lastname string
role string
);
Saya berasumsi bahwa Anda menetapkan opsi config.active_record.whitelist_attributes = true
di config / environment / production.rb Anda untuk melindungi aplikasi Anda dari eksploitasi penugasan massal. Ini dijelaskan di sini: Penugasan Massal
Model Rails Anda akan bekerja dengan baik dengan Model di bawah ini:
class User < ActiveRecord::Base
end
Namun Anda perlu memperbarui setiap atribut pengguna secara terpisah di controller Anda agar Tampilan formulir Anda berfungsi:
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
Sekarang untuk memudahkan hidup Anda, Anda tidak ingin membuat pengontrol yang rumit untuk model Pengguna Anda. Jadi Anda akan menggunakan attr_accessible
metode khusus dalam model Kelas Anda:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
end
Jadi, Anda dapat menggunakan "jalan raya" (penugasan massal) untuk memperbarui:
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
Anda tidak menambahkan atribut "peran" ke attr_accessible
daftar karena Anda tidak membiarkan pengguna mengatur sendiri peran mereka (seperti admin). Anda melakukannya sendiri di Tampilan admin khusus lain.
Meskipun tampilan pengguna Anda tidak menampilkan bidang "peran", bajak laut dapat dengan mudah mengirim permintaan HTTP POST yang menyertakan "peran" dalam hash params. Atribut "peran" yang hilang pada attr_accessible
adalah untuk melindungi aplikasi Anda dari itu.
Anda masih dapat memodifikasi atribut user.role Anda sendiri seperti di bawah ini, tetapi tidak dengan semua atribut secara bersamaan.
@user.role = DEFAULT_ROLE
Kenapa Anda akan menggunakan attr_accessor
?
Nah, ini dalam kasus bahwa formulir pengguna Anda menunjukkan bidang yang tidak ada di tabel pengguna Anda sebagai kolom.
Misalnya, katakanlah tampilan pengguna Anda menunjukkan bidang "tolong-beri tahu admin bahwa saya di sini". Anda tidak ingin menyimpan info ini di tabel Anda. Anda hanya ingin Rails mengirimi Anda email yang memperingatkan Anda bahwa satu "gila" ;-) pengguna telah berlangganan.
Untuk dapat menggunakan informasi ini, Anda perlu menyimpannya sementara di suatu tempat. Apa yang lebih mudah daripada memulihkannya di user.peekaboo
atribut?
Jadi, Anda menambahkan bidang ini ke model Anda:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
attr_accessor :peekaboo
end
Jadi Anda akan dapat menggunakan user.peekaboo
atribut yang terdidik di suatu tempat di controller Anda untuk mengirim email atau melakukan apa pun yang Anda inginkan.
ActiveRecord tidak akan menyimpan atribut "peekaboo" di tabel Anda ketika Anda melakukan user.save
karena dia tidak melihat kolom yang cocok dengan nama ini dalam modelnya.
attr_accessor
digunakan untuk menghasilkan metode pengambil dan penyetel. Silakan lihat jawaban saya untuk pertanyaan sebelumnya untuk penjelasan yang cukup komprehensif tentangattr_accessible
: stackoverflow.com/questions/2652907/… kemudian perbarui pertanyaan Anda jika Anda memerlukan detail spesifik lainnya setelah itu.