Ruby on rails 生产中Rails数据库中无法解释的大量购物车
我使用Rails 5、postgres和heroku构建了一个电子商务应用程序,使用session对象存储购物车id的经典购物车。感谢heroku的警告,我发现数据库中购物车的数量以一种非常奇怪的方式增加。每分钟可超过50次;这并不是因为有很多客户访问该网站,目前该网站规模相当小。在其他时刻,Carts表的行数是稳定的 这是我的应用程序控制器:Ruby on rails 生产中Rails数据库中无法解释的大量购物车,ruby-on-rails,postgresql,session,heroku,shopping-cart,Ruby On Rails,Postgresql,Session,Heroku,Shopping Cart,我使用Rails 5、postgres和heroku构建了一个电子商务应用程序,使用session对象存储购物车id的经典购物车。感谢heroku的警告,我发现数据库中购物车的数量以一种非常奇怪的方式增加。每分钟可超过50次;这并不是因为有很多客户访问该网站,目前该网站规模相当小。在其他时刻,Carts表的行数是稳定的 这是我的应用程序控制器: class ApplicationController < ActionController::Base protect_from_forg
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
around_action :switch_locale
before_action :configure_permitted_parameters, if: :devise_controller?
before_action :current_cart
after_action :store_action
def switch_locale(&action)
locale = params[:locale] || I18n.default_locale
I18n.with_locale(locale, &action)
end
def default_url_options
{ locale: I18n.locale == I18n.default_locale ? nil : I18n.locale }
end
def current_cart
if session[:cart_id]
cart = Cart.find_by_id(session[:cart_id])
if cart == nil
session[:cart_id] = nil
end
if cart.present?
@current_cart = cart
else
session[:cart_id] = nil
end
end
if session[:cart_id] == nil
@current_cart = Cart.create
session[:cart_id] = @current_cart.id
end
end
def store_action
return unless request.get?
if (request.path != "/users/sign_in" &&
request.path != "/users/sign_up" &&
request.path != "/users/password/new" &&
request.path != "/users/password/edit" &&
request.path != "/users/confirmation" &&
request.path != "/users/sign_out" &&
!request.xhr?) # don't store ajax calls
store_location_for(:user, request.fullpath)
end
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
end
class OrdersController < ApplicationController
before_action :authenticate_user!
def create
@order = Order.new
total = []
@current_cart.order_items.each do |item|
total << item.product.price_cents * item.quantity.to_i
end
@order.amount_cents_cents = total.sum
if @order.amount_cents_cents == 0
Cart.destroy(session[:cart_id])
session[:cart_id] = nil
redirect_to root_path
else
@current_cart.order_items.each do |item|
@order.order_items << item
item.cart_id = nil
end
@user = current_user
@order.user_id = @user.id
@order.save
Cart.destroy(session[:cart_id])
session[:cart_id] = nil
redirect_to order_path(@order)
end
昨天我删除了生产数据库的所有cart,今天我已经有3000多行了。这听起来很糟糕。是否有人可以帮助解决此问题?如果我正确阅读了您的代码:
before_action :current_cart
def current_cart
...
if session[:cart_id] == nil
@current_cart = Cart.create
session[:cart_id] = @current_cart.id
end
end
ApplicationController
中添加的将对继承自ApplicationController
的每个控制器中的每个操作执行
甚至你的主页也可能执行它。当session[:cart\u id]
为nil(根据您当前的问题,这种情况经常发生)时,每次访问都将创建一个cart
IMO的当前购物车
的目的与当前购物车用户
相同,是查找购物车,而不是创建购物车。如果它不存在,那么其他动作的目的就是创造它
你应该稍微修改一下你的逻辑。祝你好运 如果我正确阅读了您的代码:
before_action :current_cart
def current_cart
...
if session[:cart_id] == nil
@current_cart = Cart.create
session[:cart_id] = @current_cart.id
end
end
ApplicationController
中添加的将对继承自ApplicationController
的每个控制器中的每个操作执行
甚至你的主页也可能执行它。当session[:cart\u id]
为nil(根据您当前的问题,这种情况经常发生)时,每次访问都将创建一个cart
IMO的当前购物车
的目的与当前购物车用户
相同,是查找购物车,而不是创建购物车。如果它不存在,那么其他动作的目的就是创造它
你应该稍微修改一下你的逻辑。祝你好运 我认为这不能通过静态代码分析来解决。也许你应该添加一些调试日志。谢谢你的回答@LaurenzAlbe,我用Heroku logsI编辑了这个问题。在几秒钟的时间间隔内,我在日志中看到了许多来自同一源的
GET”/en/carts/:id“
调用。那可能是某种蜘蛛或机器人。您可以研究使用rack攻击来阻止这类事情,但首先您应该了解GET请求创建购物车的原因,在您有东西放入购物车之前,您不应该创建购物车。我认为这不能通过静态代码分析来解决。也许你应该添加一些调试日志。谢谢你的回答@LaurenzAlbe,我用Heroku logsI编辑了这个问题。在几秒钟的时间间隔内,我在日志中看到了许多来自同一源的GET”/en/carts/:id“
调用。那可能是某种蜘蛛或机器人。您可以研究使用rack攻击来阻止这类事情,但首先您应该了解GET请求创建购物车的原因,在您有东西放入购物车之前,您不应该创建购物车。我想您就在这里,GET”/en/carts/:id“
可能不应该创建购物车。谢谢@razvans和mu太短了!我修改了代码,以便仅在需要时创建购物车。它还不是完美的,但是Cart.count在Heroku控制台中一个小时内是0,所以这是一种解脱!然而,你认为使用rack attack是否仍然有用,就好像该站点曾经是目标一样,它可能是其他危险的爬行器或机器人的目标?如果你有rack attack,你可能不会发现这个问题。我说你要确保所有的端点都是安全的、优化的、快速的,然后机器人是无害的。我想你就在这里,GET”/en/carts/:id“
可能不应该创建一个购物车。谢谢@razvans和mu太短了!我修改了代码,以便仅在需要时创建购物车。它还不是完美的,但是Cart.count在Heroku控制台中一个小时内是0,所以这是一种解脱!然而,你认为使用rack attack是否仍然有用,就好像该站点曾经是目标一样,它可能是其他危险的爬行器或机器人的目标?如果你有rack attack,你可能不会发现这个问题。我说你要确保所有的端点都是安全的、优化的、快速的,然后机器人是无害的。
before_action :current_cart
def current_cart
...
if session[:cart_id] == nil
@current_cart = Cart.create
session[:cart_id] = @current_cart.id
end
end