Skip to content

Instantly share code, notes, and snippets.

@slavone
Last active November 14, 2015 10:43
Show Gist options
  • Save slavone/25cd352ff6550b10519d to your computer and use it in GitHub Desktop.
Save slavone/25cd352ff6550b10519d to your computer and use it in GitHub Desktop.
purchase_review

В том виде, в котором сформулировано задание, кнопка покупки никак не связана с товаром. Если же покупка зависела бы от ID товара, то можно было бы передавать этот ID в виде параметров URL'а, и вроде тоже никаких проблем. Так что проблема с покупкой сводится только к делегации прав юзеров - ограничить доступ в контроллере, и видимость во views. Поэтому все вопросы из предыдущего пунка актуальны и здесь.

Для обработки запроса покупки я создал контроллер purchases_controller, откликающийся на один единственный метод new. По логике, что new - новая покупка. Стоит ли здесь придерживаться RESTful терминологии, или же особого смысла это не имеет?

Далее, при покупке нужно считать один случайный JSON со страницы. Я считывал всю страницу через JSON.load, и делал .sample полученной коллекции для получения случайного. Просто считать со страницы случайную запись, не подгружая ее полностью кажется мне невозможным, но может быть я ошибаюсь? Насколько сильно стоит логически отделять функционал такого типа(взаимодействия с API другого приложения) в свои методы или классы от контроллера? Ошибки при покупке пользователю выдаются через flash оповещение. Значения из ссылок для проверки правильности парсил REGEX'ом, нахождения мыла юзера в .com домене проверял также.

Для отсылки писем создал purchase_mailer, с этим вроде ничего сложного. Для получения email'ов всех админов написал метод, mail to: может принимать массив адресов. Данные из контоллера в мэйлер передаются как параметры метода мэйлера.

Так как я ресетил БД после первой части, у меня не осталось не привязанных к магазину товаров, поэтому, для удобства, я добавил возможность добавлять владельцу магазина товары, не ассоциируя их со своим магазином. Тогда поле shop_name у товара просто остается пустым.

class PurchaseMailer < ApplicationMailer
def purchase_success(user_email, purchase_data)
@purchase = purchase_data
mail to: user_email, subject: "Successful purchase"
end
def alert_admins_about_purchase(admin_data)
@admin_data = admin_data
mail to: all_admins, subject: "User purchased product"
end
def purchase_failure(user_email)
@email = user_email
mail to: all_admins, subject: "User failed to make a purchase"
end
private
def all_admins
UserLogin.where(user_type: 'Admin').pluck(:email)
end
end
class PurchasesController < ApplicationController
before_action :can_user_purchase_products?
def new
url_get = URI('http://jsonplaceholder.typicode.com/photos/')
url_post = URI('http://jsonplaceholder.typicode.com/todos')
@purchase_data = JSON.load(url_get).sample
if purchase_data_valid?(@purchase_data)
post_response = Net::HTTP.post_form(url_post, {})
admin_data = JSON.parse(post_response.body)
PurchaseMailer.purchase_success(current_user.email, @purchase_data).deliver_now
PurchaseMailer.alert_admins_about_purchase(admin_data['id']).deliver_now
flash[:success] = "You purchased this product!"
else
PurchaseMailer.purchase_failure(current_user.email).deliver_now
flash[:danger] = "Purchase failed, because 'thumbnailUrl' attribute is 'bigger' than 'url' attribute."
end
redirect_to products_path
end
private
def purchase_data_valid?(data)
regex_extract_hex = /\/([a-f0-9]+)$/
thumbnail_url = data['thumbnailUrl'].match(regex_extract_hex)[1]
url = data['url'].match(regex_extract_hex)[1]
thumbnail_url.hex < url.hex
end
def can_user_purchase_products?
unless logged_in? && current_user.is_guest?
flash[:danger] = 'Only registered guest users can buy products.'
redirect_to root_path
return
end
if current_user.email.match(/\.com$/)
flash[:danger] = 'Users with emails in .com domain cant purchase products. Sorry :('
redirect_to products_path
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment