使用按钮设置cookie并在cookie中显示视图中的值

时间:2017-07-15 06:22:44

标签: ruby-on-rails cookies

我正在构建一个服务rails应用程序,客户可以订购3种不同的服务,但根据所选择的服务,将有不同的价格和细节。

我不想为我的订单制作很多表格,所以我试图制作不同的订单Cookie,根据用户点击的按钮存储整数,然后根据Cookie值显示订单价格和订单详情,例如周转时间。

截至目前,我尝试在按钮点击时存储Cookie,如<%= link_to 'Package 1', controller:'order, action:'order_one'%>

在我的路线中定义,例如get 'order_one', to: 'order#order_one', as: 'order_one',即使我已定义resources: order

在我的控制器中定义了order_one方法:

 def order_one
  cookies[:orderref]=1
  redirect_to '/order'
end

并在before_action方法上调用capture_order cookies[:orderref] = params[:orderref] if params[:orderref]

当我点击order_one链接按钮时,它只刷新主页,所以我不确定在设置此cookie时我做错了什么。

编辑:已添加订单

class OrderController < ApplicationController
  
  before_action :set_user, except: [:new, :create]
  before_action :set_admin, only: [:edit, :update, :destroy]
  before_action :capture_order_cookie

  def new
    @order = Order.new
    
    #TODO: Handling the cookie's here
    if cookies[:orderref] == 1 #Custom Text
      #TODO: price
    elsif cookies[:orderref] == 2 #Custom Text & Custom Imagery

    elsif cookies[:orderref] == 3 #Custom Text & Custom Cartoon
      #might run into a problem bc order isn't created and am trying to set price before creation, could just put price later on?
    end
    
  end
  
  def index
    #TODO: AJAX so order's disappear from view when status changes
    @orders = Order.all #TODO: maybe limit this?
    @orders_user = current_user.orders.where(status:2)
    @orders_user_completed = current_user.orders.where(status: 4 || 5)
    #Admin stuff
    @orders_active = @orders.where(status: 2) 
    @orders_review = @orders.where(status: 3) 
    @orders_completed_not_paid = @orders.where(status: 4) 
    @orders_all_completed = @orders.where(status: 5) 
    
  end
  
  def create
    @order = Order.where(order_params).first_or_create
    @order.status = 1
    if @order.save
      flash[:success] = "Order was successfully made"
      redirect_to root_path
    else
      #flash error
      flash[:error] = "Error making order"
      render 'new'
    end
  end
  
  def edit
    @order = set_order
  end
  
  def update
    @order = set_order
    if @order.update(order_params)
      flash[:success] = "Order was successfully updated"
      redirect_to dashboard_path
    else
      flash[:error] = "Error updating"
      render 'edit'
    end
  end
  
  def destroy
    #TODO: destroy for orders that were refunded/cancelled
  end
  
  #Accepting order & adding user_id to order
  def accept
    @order = set_order
    if @order.user_id.present?
      redirect_to root_path, flash[:error]='Order already taken'
    else
      @order.update(user_id: current_user.id)
      @order.update(status: 2)
      if @order.save
        redirect_to root_path, flash[:success]='Order accepted'
      else
        flash[:error]='Couldn`t process your request'
      end
    end
  end
  
  #Submitting order for review
  def submit
    @order = set_order
    @order.update(status: 3)
    if @order.save
      redirect_to dashboard_path, flash[:success]='Order submitted for review'
    else
      redirect_to dashboard_path, flash[:error]='Request failed'
    end
  end
  
  def order_one
    cookies.permanent[:orderref]=1
    redirect_to '/order'
  end
  
  private
  def order_params
    params.require(:order).permit(:name, :company, :email, :event_type, :status, :country, :description, :user_id, :admin_comments,
                                  :revision_comments)
  end
  
  def set_order
    @order = Order.find(params[:id])
  end
  
  def set_user
    if !current_user
      redirect_to root_path
    end
  end
  
  def set_admin
    if !current_user.admin
      if current_user
        redirect_to dashboard_path
      end
    redirect_to root_path
    end
  end
  
  def capture_order_cookie #could do the IFs here?
    cookies.permanent[:orderref] = params[:orderref] if params[:orderref]
  end
end

2 个答案:

答案 0 :(得分:0)

正如评论中所讨论的,set_user方法将您重定向到root_url,如果您想要保存cookie,即使用户未登录,也请将过滤器移至第一行

before_action :capture_order_cookie
before_action :set_user, except: [:new, :create]
before_action :set_admin, only: [:edit, :update, :destroy]

此外,set_user方法不是它应该的方式,将其重命名为verify_session,或者如果您使用的是设计,则它有一个帮助authenticate_user

答案 1 :(得分:0)

基于不需要使用cookie(它们只是找到的可能解决方案,请参阅有关问题的评论)。我提出了一个不同的解决方案。

首先,您可以将查询参数传递给/orders/new?orderref=1(我假设您在执行redirect_to '/order'时打算发送它们,因为这将是索引操作)

<%= link_to 'Package 1', new_order_path(orderref: 1) %>

并使用params[:orderref]在控制器中访问它(这将是一个字符串)并根据该设置启动。

如果您不想这样做,下一个最简单的方法可能是使用默认参数设置路线:

<强>配置/ routes.rb中

get 'order_one', to: 'orders#new', defaults: { orderref: 1 }, as: :order_one
get 'order_two', to: 'orders#new', defaults: { orderref: 2 }, as: :order_two
get 'order_three', to: 'orders#new', defaults: { orderref: 3 }, as: :order_three

应用/控制器/ orders_controller.rb

def new
  @order = Order.new

  # TODO: setup custom pricing, etc. here
  case params[:orderref]
  when 1
    @message = "Here with order 1"
  when 2
    @message = "Order Ref is 2"
  when 3
    @message = "Received the third"
  else
    @message = "No Order Ref received"
  end
end

应用/视图/命令/ new.html.erb

<%= content_tag(:small, @message) %>

最后是指向该页面的链接

<%= link_to 'Package 1', order_one_path %>
<%= link_to 'Package 2', order_two_path %> 
<%= link_to 'Package 3', order_three_path %>

现在,您可以将用户定向到/order_one,他们将继续new行动,同时停留在/order_one路线上(而不是被推入/orders/new

如果您想让它们转到/orders/new,您只需使用session

<强>配置/ routes.rb中

get 'order_four', to: 'orders#order_four'

应用/控制器/ orders_controller.rb

def new
  @order = Order.new

  case session[:orderref]
  when 4
    @message = "From session"
  else
    @message = "No Order Ref received"
  end

  # clear the value from the session, so it's not lingering around
  # maybe you'll want to do this after creating an order?
  session[:orderref] = nil if session[:orderref]
end

# Might need to add this to the `:except` list for `set_user`
def order_four
  session[:orderref] = 4

 redirect_to new_order_path
end

并且如果这是一项要求,则会将它们保留在/orders/new而不是每个包的自定义网址,而不是查询参数。