#ruby-on-rails
#ruby-on-rails
Вопрос:
Я пытаюсь создать корзину, которую можно использовать, даже если пользователь не входит в систему. В настоящее время я использую сеансы для этого, однако объект cart не будет сохранен, если не будет ассоциации с пользователем. Каков наилучший способ обойти это?
Вот мой код
class Cart < ApplicationRecord
belongs_to :user
has_many :cart_items, dependent: :destroy
has_many :products, through: :cart_items
monetize :price_cents
end
#Application Controller
def current_customer
@user = User.find(session[:user_id]) if session[:user_id]
end
def current_shopping_cart
if login?
@cart = @user.cart
else
if session[:cart]
@cart = Cart.find(session[:cart])
else
@cart = Cart.create(delivery: "self-collection")
session[:cart] = @cart.id
end
end
end
def login?
!!current_customer
end
Комментарии:
1. belongs_to займет
optional: true
.2. PG:: NotNullViolation: ОШИБКА: значение null в столбце «user_id» нарушает ограничение not-null
3. t.bigint «user_id», null: false <- Должен ли я изменить это тогда?
4. что вам нужно, так это изменить строку belongs_to :user на belongs_to :user, необязательно: true
5. Да, измените
user_id
столбец в базе данных наnot null
too .
Ответ №1:
Чтобы сделать ассоциацию необязательной, вам нужно сделать столбец базы данных обнуляемым:
class ChangeCartsUserId < ActiveRecord::Migration[6.0]
def change
change_column_null :carts, :user_id, true
end
end
И сделайте ассоциацию необязательной:
class Cart < ApplicationRecord
belongs_to :user, optional: true
# ...
end
Это просто удаляет validates_presence_of
проверку, добавленную ассоциациями belongs_to по умолчанию, начиная с Rails 5.
Другой способ решения этой проблемы — создать учетную запись «гостевого пользователя», как только пользователь добавит свой первый товар в корзину, и войти в систему. Вы бы объединили это с повторяющимся заданием для удаления неполных извлечений с течением времени.