使用Ruby on Rails将布尔值保存到PostgreSQL数据库

5
我已经在一个旧的rails项目上工作一段时间了。由于我有一段时间没有使用rails,我有些生疏,需要一些帮助。
问题是我正在为电子商务网站增加取货选项。
后端由active admin驱动。
当客户结账时,他可以选择在店里取货或者邮寄。
我希望订单在后台显示商品是应该邮寄还是在店里取货。
我有些困惑,似乎交付选项没有保存到数据库中...如果有人能帮我解决这个问题就太好了。
以下是取货选项的html,它位于views/orders/_form.html.erb中。
<div class="col-md-5 pick-up-buttons" id="country_div">
  <li>
    <%= f.radio_button :pick_up, "1", checked: false, data: { question: "Pick up your items in the store" } %> 
    <%= f.label :pick_up, "Pick up your items in the store" %>
  </li>
  <li>
    <%= f.radio_button :pick_up, "0", checked: true,  data: { question: "Send the items by mail" } %> 
    <%= f.label :pick_up, "Send the items by mail" %>
  </li>
</div> 

这里是 schema.rb 文件的一部分。

create_table "orders", force: :cascade do |t|
  t.string   "name"
  t.string   "email"
  t.text     "address"
  t.string   "city"
  t.string   "country"
  t.datetime "created_at",                 null: false
  t.datetime "updated_at",                 null: false
  t.boolean  "shipped",    default: false
  t.boolean  "pick_up",    default: false
  t.string   "delivery"
end

这里是orders_controller.rb文件。

class OrdersController < ApplicationController
  include CurrentCart
  before_action :set_cart, only: [:new, :create]
  before_action :set_order, only: [:show, :edit, :destroy]

  def index
    @orders = Order.all? 
  end

  def new
    @images  = ["1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg"]
    @random_no = rand(5)
    @random_image = @images[@random_no]

    if @cart.product_items.empty?
      redirect_to root_url, notice: 'Your Cart is Empty'
      return
    end

    @order = Order.new
    @client_token = Braintree::ClientToken.generate

    @del_cost_euro = 20
  end

  def create
    @order = Order.new(order_params)
    if @order.save
      charge
      if @result.success?
        @order.add_product_items_from_cart(@cart)
        Cart.destroy(session[:cart_id])
        session[:cart_id] = nil
        OrderNotifier.received(@order).deliver 
        redirect_to root_url, notice: 'Thank You for Your Order'
      else
        flash[:error] = 'Please Check Your Cart'
        redirect_to root_url, alert: @result.message
        @order.destroy
      end
    else
      @client_token = Braintree::ClientToken.generate
      render :new
    end
  end

  def show
  end

  def destroy
    @order.destroy
    redirect_to root_url, notice: 'Order deleted'
  end

  private
  def set_order
    @order = Order.find(params[:id])
  end

  def order_params
    params.require(:order).permit(:name, :email, :address, :city, :country, :pick_up, :delivery)
  end

  def charge
    @result = Braintree::Transaction.sale(
      amount: @cart.total_price_usd,
      payment_method_nonce: params[:payment_method_nonce] )
  end
end

以下是 app/admin/order.rb 的内容:

ActiveAdmin.register Order do

permit_params :shipped

after_update do |order|
  OrderNotifier.shipped(@order).deliver if order.shipped
end

show do |order|
  panel 'Customer Details' do
    attributes_table_for order, :name, :email, :address, :city, :country
  end

  panel 'Created' do
    "#{time_ago_in_words order.created_at} ago"
  end

  panel 'Shipped' do
    order.shipped
  end

  panel 'delivery' do
    order.pick_up
  end

  panel 'Order Details' do
    table_for(order.product_items) do 
      column 'Product' do |item|
        item.product.title
      end

      column 'Quantity' do |item|
        item.quantity
      end

      column 'Price Euro' do |item|
        number_to_currency item.total_price_eur
      end

      column 'Price USD' do |item|
        number_to_currency item.total_price_usd
      end
    end
  end

  panel 'Order Total USD' do 
    number_to_currency order.total_price_usd
  end

  panel 'Order Total Euro' do 
    number_to_currency order.total_price_eur
  end
end

你尝试过使用radio_button_Tag吗?https://apidock.com/rails/ActionView/Helpers/FormTagHelper/radio_button_tag - Gabriel Mesquita
还有一件事,你觉得单选按钮对于这个功能来说正确吗?下拉选择框不更好吗? - Gabriel Mesquita
嗨 @GabrielMesquita,我还没有使用 radio_button_Tag... 我不确定这个功能应该怎么做才正确,也许选择下拉框会更好。我有点迷失在这一切中 :) 你能发一下你会怎么做吗? - codegirl
好的,我会尝试。 - Gabriel Mesquita
1
我强烈建议您使用一个名为delivery_type(字符串)的列,而不是pick_up(布尔值),出于灵活性的原因。然后,您可以通过验证确保此delivery_type属性的存在,并确保该值有效(使用常量作为白名单)。然后在管理页面中,只需在相关时显示delivery_type和地址即可。 - MrYoshiji
1个回答

2

所以您想知道产品是在商店取货还是通过电子邮件发送,对吗?

如果您迷失了方向,一个更简单的解决方案是:

1- 将 t.boolean “pick_up” 更改为 t.string “pick_up”

2- 使用此http://guides.rubyonrails.org/form_helpers.html#the-select-and-option-tags,创建一个包含这两个选项的列表。

3- 在控制器中保存用户想要的选项。

我认为,要使用单选按钮,您必须在数据库中有两个字段。类似于这样:

t.boolean “pick_up” t.boolean “sent_email”

如果用户选择取货,您将收到一个带有取货真值的参数,然后可以将其保存在数据库中。所以这也是另一种选择!

希望能帮到您。


1
感谢@GabrielMesquita,我不确定为什么我应该将t.boolean更改为字符串,因为布尔值只能是true或false。数据库将看到true = 发送产品或false = 取货产品。 - codegirl
1
@codegirl 布尔类型就像你说的那样,是真或假(或者是nil,但这应该由你的代码/数据库处理)。如果明天你的老板想要添加另一种交付方式,比如“鸽子”,你将不得不将此布尔列转换为字符串类型,并根据其当前值更新现有数据等。看到我要说什么了吗?你正在实现一个可能变成更大的功能,尝试立即生成灵活的代码/数据库结构,这样如果发生这种情况,你就不必花费太多的精力。 - MrYoshiji
就像@MrYoshiji所说,字符串更加灵活,我认为它可以解决你的问题。如果这个答案有帮助,请点赞 :) - Gabriel Mesquita

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接