Mengingat asosiasi berikut ini, saya perlu merujuk Question
bahwa a Choice
dilampirkan melalui Choice
model. Saya telah berusaha menggunakan belongs_to :question, through: :answer
untuk melakukan tindakan ini.
class User
has_many :questions
has_many :choices
end
class Question
belongs_to :user
has_many :answers
has_one :choice, :through => :answer
end
class Answer
belongs_to :question
end
class Choice
belongs_to :user
belongs_to :answer
belongs_to :question, :through => :answer
validates_uniqueness_of :answer_id, :scope => [ :question_id, :user_id ]
end
Saya mendapatkan
NameError konstanta tidak diinisialisasi
User::Choice
ketika saya coba lakukan current_user.choices
Ini berfungsi dengan baik, jika saya tidak memasukkan
belongs_to :question, :through => :answer
Tetapi saya ingin menggunakannya karena saya ingin dapat melakukan itu validates_uniqueness_of
Saya mungkin menghadap sesuatu yang sederhana. Bantuan apa pun akan dihargai.
Jawaban:
Sebuah
belongs_to
asosiasi tidak dapat memiliki:through
pilihan. Anda lebih baik melakukan cachingquestion_id
onChoice
dan menambahkan indeks unik ke tabel (terutama karenavalidates_uniqueness_of
rentan terhadap kondisi balapan).Jika Anda paranoid, tambahkan validasi khusus ke
Choice
yang mengonfirmasi bahwa jawabannyaquestion_id
cocok, tetapi sepertinya pengguna akhir tidak boleh diberi kesempatan untuk mengirimkan data yang akan membuat ketidakcocokan seperti ini.sumber
Anda juga dapat mendelegasikan:
sumber
Cukup gunakan
has_one
alih-alihbelongs_to
dalam:through
, seperti ini:Tidak terkait, tetapi saya akan ragu untuk menggunakan validates_uniqueness_of daripada menggunakan batasan unik yang tepat dalam database Anda. Ketika Anda melakukan ini di ruby Anda memiliki kondisi balapan.
sumber
autosave: false
diatur.Pendekatan saya adalah membuat atribut virtual alih-alih menambahkan kolom basis data.
Pendekatan ini cukup sederhana, tetapi disertai dengan pengorbanan. Itu membutuhkan Rails untuk memuat
answer
dari db, dan kemudianquestion
. Ini dapat dioptimalkan nanti dengan bersemangat memuat asosiasi yang Anda butuhkan (yaituc = Choice.first(include: {answer: :question})
), namun, jika optimasi ini diperlukan, maka jawaban stephencelis mungkin merupakan keputusan kinerja yang lebih baik.Ada waktu dan tempat untuk pilihan tertentu, dan saya pikir pilihan ini lebih baik ketika membuat prototipe. Saya tidak akan menggunakannya untuk kode produksi kecuali saya tahu itu untuk kasus penggunaan yang jarang.
sumber
Sepertinya yang Anda inginkan adalah Pengguna yang memiliki banyak Pertanyaan.
Pertanyaan memiliki banyak Jawaban, salah satunya adalah Pilihan Pengguna.
Apakah ini yang Anda cari?
Saya akan memodelkan sesuatu seperti itu di bawah ini:
sumber
Jadi Anda tidak dapat memiliki perilaku yang Anda inginkan tetapi Anda dapat melakukan sesuatu yang terasa seperti itu. Anda ingin dapat melakukannya
Choice.first.question
apa yang telah saya lakukan di masa lalu adalah sesuatu seperti ini
dengan cara ini Anda sekarang dapat mengajukan pertanyaan pada Pilihan
sumber
The
has_many :choices
menciptakan sebuah asosiasi yang bernamachoices
, tidakchoice
. Coba gunakancurrent_user.choices
sebagai gantinya.Lihat dokumentasi ActiveRecord :: Associations untuk informasi tentang
has_many
sihir.sumber