我是Rails的新手,正在建立一个电子商务应用程序。我会感激任何帮助。我的电子商务应用程序允许访客(使用购物车的会话 - 购物车会话在创建订单后重置)和登录用户签出(使用设计)。创建订单后,生成订单的人员将被定向到订单显示页面,在那里他们可以查看订单的详细信息并下载pdf(通过wicked_pdf)订单的详细信息。但是,问题是我的订单显示页面网址引用了订单ID,即localhost:3000 / orders / [:id],因此任何没有订单的人都可以轻松输入网址来检索订单详细信息。如果它只是登录可以结帐的用户,那么我可以将页面仅限制为current_user,但问题是当它是访客结账时。
我的解决方案是通过在订单控制器中的show动作中声明仅当订单存在时隐藏其他用户的订单显示页面,然后显示展示页面,否则重定向到根页面。这适用于显示页面的第一次渲染(在创建订单后立即),但是如果我单击显示页面上的pdf,它将不再检测order.id,而是重定向到根页面。因此,虽然解决方案部分用于确保转到/ orders / [:id]的任何人被重定向到root_path,但它也可以将我的pdf请求定向到root_path。
我的订单控制器代码是:
class OrdersController < ApplicationController
include CurrentCart
before_action :set_cart, only: [:new, :create, :show]
before_action :set_order, only: [:show, :edit, :destroy]
def new
if user_signed_in?
@order = current_user.orders.new
else
@order = Order.new
end
@client_token = Braintree::ClientToken.generate
end
def create
if user_signed_in?
@order = current_user.orders.new(order_params)
else
@order = Order.new(order_params)
end
if @order.save
@order.regenerate_auth_token
charge
if @result.success?
@order[:total_price] = @cart.total_price
@order.save
##Add_carted_activities_from_cart is in cart model - this is what makes the cart go to nil
@order.add_carted_activities_from_cart(@cart)
Cart.destroy(session[:cart_id])
session[:cart_id] = nil
render :show, notice: 'Thank You for Your Order!'
else
flash[:error] = 'Check Your Cart'
redirect_to new_order_path, alert: @result.message
@order.destroy
end
else
@client_token = Braintree::ClientToken.generate
render :new
end
end
def show
if params.has_key?(:order)
respond_to do |format|
format.html
format.pdf do
render pdf: "order",
template: "orders/show.pdf.erb"
end
end
else
redirect_to root_path
end
end
def destroy
@order.destroy
redirect_to root_url, notice: 'Your Order has been deleted'
end
private
def set_order
@order = Order.find(params[:id])
end
def order_params
params.require(:order).permit(:order_status, :activity_quantity, :activity_price,
:fees, :taxes, :billing_address, :customer_name,
:total_price)
end
def charge
@result = Braintree::Transaction.sale(
amount: @cart.total_price,
payment_method_nonce: params[:payment_method_nonce])
end
端
我试过的另一个解决方案(因为我没有把代码放在这里不起作用)是使用会话。我在set_order中设置了session [:order_id] = @ order.id,并定义了after_action:destroy_session:show。 Destroy_session被定义为session [:order_id] = nil。这没有任何效果,任何人仍然可以通过在URL中输入id来查看订单详细信息。
我的订单显示页面代码
<div class = "container">
<div class = "cart">
<div class = "row">
<h3>Confirm & Pay</h3>
<div class="col-md-12">
<ul class="progressbar">
<li>Your Order</li>
<li>Confirm & Pay</li>
<li class="active">Thank You</li>
</ul>
</div>
</div>
</div>
<br>
<div class = "col-md-12">
<hr>
<center>
<div class = "panel panel-default" id = "thankyou">
<div class = "panel panel-body">
<i class="fa fa-check-circle-o fa-2x fa-pull-left" aria-hidden="true" style="-webkit-text-stroke: 2px white;"></i>
<div class = "thankyou_text">
<h5>Thank you, we've received your booking.</h5>
<p>
<h6> We will send a confirmation of your booking to <%= @order.customer_email%></h6>
</p>
</div>
</div>
</div>
<%= link_to_blank order_path(@order.id, :format => 'pdf') do %>
<i class="fa fa-file-pdf-o fa-2x" aria-hidden="true" style="color: #00a8ba;">View Details</i>
<% end %>
</center>
<div class = "summary">
<hr>
<h5 style = "text-transform: uppercase;">
Order Number: <%= @order.auth_token.slice(0..4) + @order.id.to_s %>
</h5>
<h5> Summary of your order
</h5>
<h6><% @order.carted_activities.each do |carted_activity| %>
<p> <%=carted_activity.supplier_activity_option.supplier_activity.activity.name %>
x
<%= carted_activity.activity_quantity %>
<span class = "right_side"> <%= number_to_currency carted_activity.total_price %> </span>
</p>
<% end %>
<p>Our Service Fee
<span class = "right_side"> Free </span>
</p>
<p>Taxes
<span class = "right_side">##</span>
</p>
<span class = "order_total">
<p>Order Total
<span class = "right_side"><%=number_to_currency @order.total_price %></span>
</p>
</span>
</h6>
</div>
</div>
路线文件
Rails.application.routes.draw do
get 'place_images/index'
get 'activity_images/index'
root to: 'pages#index'
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
devise_for :users, controllers: {registrations: 'users/registrations', omniauth_callbacks: "users/omniauth_callbacks"}
resources :users
get 'activities/types' => 'activities#tagged'
get '/about' => 'pages#about'
get '/search' => 'searches#search'
put 'carted_activities/qty' => 'carted_activities#updateQuantity'
get 'carts/show' => 'carts#show'
resources :countries
resources :regions
resources :carted_activities
resources :carts
resources :orders
resources :supplier_activities do
resources :reviews
end
resources :suppliers
resources :activity_images, only: [:index]
resources :place_images, only: [:index]
resources :activities, only: [:create, :index, :destroy, :show] do
resources :wishlists
end
end
我还应该做些什么来确保pdf请求检测到当前订单而不是重定向到root_path?理想情况下,我需要将订单显示网址阻止给生成订单的人以外的所有人,但生成订单的人可以查看和发送pdf给任何人。任何有关如何实现这一目标的反馈和指导都将非常感激。
答案 0 :(得分:0)
当用户加载订单显示页面时,检查订单是否由当前用户放置。
class OrdersController < ApplicationController
before_action :check_current_user, only: [:show]
def check_current_user
redirect_to root_url unless @order.user == current_user
end
答案 1 :(得分:0)
感谢大家的帮助。我现在用我的订单控制器中的创建和显示操作中的会话哈希解决了这个问题,如下所示:
def create
if user_signed_in?
@order = current_user.orders.new(order_params)
else
@order = Order.new(order_params)
end
if @order.save
@order.regenerate_auth_token
charge
if @result.success?
@order[:total_price] = @cart.total_price
@order.save
session[:order] = true
##Add_carted_activities_from_cart is in cart model - this is what makes the cart go to nil
@order.add_carted_activities_from_cart(@cart)
Cart.destroy(session[:cart_id])
session[:cart_id] = nil
render :show, notice: 'Thank You for Your Order!'
else
flash[:error] = 'Check Your Cart'
redirect_to new_order_path, alert: @result.message
@order.destroy
end
else
@client_token = Braintree::ClientToken.generate
render :new
end
end
def show
if !session[:order].blank?
respond_to do |format|
format.html
format.pdf do
render pdf: "seeksophie_order",
template: "orders/show.pdf.erb"
end
end
session.delete(:order)
else
redirect_to root_path
end
end