Hai (pemula Rails besar di sini), saya memiliki model berikut:
class Shop < ActiveRecord::Base
belongs_to :user
validates_uniqueness_of :title, :user_id, :message => "is already being used"
end
dan
class User < ActiveRecord::Base
has_one :shop, :dependent => :destroy
end
Ketika saya akan membuat toko baru, saya mendapatkan kesalahan berikut:
private method `create' called for nil:NilClass
Ini pengontrol saya:
@user = current_user
@shop = @user.shop.create(params[:shop])
Saya telah mencoba variasi yang berbeda dengan membaca panduan dan tutorial di sana-sini, tetapi saya lebih bingung daripada sebelumnya dan tidak dapat membuatnya berfungsi. Bantuan apa pun akan sangat dihargai.
ruby-on-rails
Neko
sumber
sumber
@user.build_shop(params)
Jawaban:
Pertama-tama, berikut ini cara melakukan apa yang Anda inginkan:
Sekarang, inilah mengapa versi Anda tidak berfungsi:
Anda mungkin berpikir bahwa ini mungkin berhasil karena jika Pengguna memiliki
has_many
hubungan dengan Toko,@user.shops.create(params[:shop])
akan berhasil. Namun ada perbedaan besar antarahas_many
relasi danhas_one
relasi:Dengan suatu
has_many
relasi,shops
mengembalikan objek koleksi ActiveRecord, yang memiliki metode yang dapat Anda gunakan untuk menambah dan menghapus toko ke / dari pengguna. Salah satu metode tersebut adalahcreate
, yang membuat toko baru dan menambahkannya ke pengguna.Dengan
has_one
relasi, Anda tidak akan mendapatkan kembali objek koleksi seperti itu, tetapi cukup objek Toko yang dimiliki pengguna - atau nol jika pengguna belum memiliki toko. Karena baik objek Shop maupun nil tidak memilikicreate
metode, Anda tidak dapat menggunakancreate
cara ini denganhas_one
relasi.sumber
@user.create_shop(params[:shop])
. Lihat metode yang ditambahkan oleh has_one .Cara yang lebih ringkas untuk melakukannya adalah dengan:
Lihat metode yang ditambahkan oleh has_one di panduan Ruby on Rails.
sumber
@user.create_shop(params[:shop_one_info])
akan membuat shop_one, TETAPI jika dijalankan@user.create_shop(params[:shop_two_info])
itu akan menghapus toko pertama dan membuat yang kedua.@user.build_shop(params)
Dua cara lagi jika Anda mau,
save
bukancreate
:sumber
Hanya untuk menambah jawaban di atas -
Sintaks di atas membuat rekaman baru tetapi kemudian menghapus rekaman serupa yang sudah ada.
Alternatifnya, jika Anda tidak ingin memicu delete callback
Utas ini mungkin bisa membantu. Klik disini
sumber