Skip to content

Instantly share code, notes, and snippets.

@annikoff
Last active October 13, 2016 16:28
Show Gist options
  • Save annikoff/0e451414a9b1280a6b46a5336be9ccf0 to your computer and use it in GitHub Desktop.
Save annikoff/0e451414a9b1280a6b46a5336be9ccf0 to your computer and use it in GitHub Desktop.
# В соответствии с соглашениями название должно быть BasketsController
# насколько понимаю, мы находимся в контексте Rails приложение, значит контроллер должен наследоваться от ApplicationController
class BasketController
# на мой взгляд add_item — это более удачное название метода
def add_to_basket
# Правильно будет искать по id товара
# при этом поиск товара лучше вынести в отдельный метод
# def item
# @item ||= Item.find params[:id]
# end
item = Item.find_by_title(params[:item_title])
# использована глобальная переменная $basket,
# полагаю, что получение корзины тоже лучше вынести в отдельный метод
basket = $basket
basket.add_item(item)
# валидацию нужно вынести в модель Basket,
if basket.count_items > 10
# сообщение
basket.error_messages.add("Слишком много товаров в корзине")
end
# Подсчёт общей суммы должен быть в моделе Basket
# def total_price
# items.sum(:price)
# end
total = 0
basket.items.each do |basket_item|
total += basket_item.price
end
# session[:basket_total] = basket.total_price
# т.к. корзина и товары в ней сохранены, то вероятно нет необходимости писать данные в сессию
session[:basket_total] = total
# Оператор INSERT написан через Z, после оператора VALUES нет скобки
# вместо id товара использовано название
# Работа с БД не должна произвоидится в контроллере
# Нет необходмости использовать "сырой" SQL, т.к. есть ActiveRecord,
# за создание записей в таблице basket_items должна отвечать модель BasketItem,
query = "INZERT INTO basket_items (basket_id, item_title, basket_type) VALUES '" +
# вместо точки использована стрелка,
(basket->basket_id.to_s) + "', '" + params[:item_title] + "', 3)"
results = ActiveRecord::Base.connection.execute(query)
# Корзина сама должна определять бесплатность доставки, нет необходимости вызывать этот метот здесь
Basket.add_free_delivery(basket)
# результат не будет выведен на экран, т.к. есть в есть view отвечающий за этот метод,
# то данные нужно передать в него через переменную
#
# Вероятно что вызов метода add_to_basket происходит с клиента асинхронно,
# поэтому в качестве результата предлагаю возвращать сериализованный объект корзины с товарами
return "<h1>Добавлен товар в корзину: #{item.title}</h1>"
end
end
# В общих чертах, как я себе это представляю
class BasketsController < ApplicationController
# ...
def add_item
basket.add_item(item)
if basket.save
render :show, :status => 200
else
render :error, :status => 422
end
end
private
def item
@item ||= Item.find params[:id]
end
# Предположим, что есть current_user
def basket
@basket ||= current_user.basket
end
end
class Basket < ActiveRecord::Base
has_many :basket_items
has_many :items, through: :basket_items
validate do
check_items_numbers
end
before_save :add_free_delivery
# ...
def add_item(item)
# ...
end
def total_price
items.sum(:price)
end
private
def add_free_delivery
# ...
end
def check_items_numbers
# валидация о добавление ошибки, при необходимости
end
end
class BasketItem < ActiveRecord::Base
belongs_to :basket
belongs_to :item
# ...
end
class Item < ActiveRecord::Base
# ...
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment