5

I've been working on a old rails project for a bit now. Since I haven't worked with rails in some time I'm a bit rusty and need some help along the way.

The thing is that I'm adding a pick up options to a E commerce web.

The backend is driven by active admin

When the customer is checking out its product. He gets the option to pick it up in the store or have it sent.

And I want the order to show in the backend whether the product should be sent or if it is picked up at the store.

I'm kind of stuck here, and the delivery options don't seems to be saving to the database.... It would be so nice if someone could help me with this.

here is the html for the pick up option. it is located in the 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> 

and here is a part of the schema.rb file

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

And here is the 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

And here is the 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
5
  • Have you tried to use radio_button_Tag? apidock.com/rails/ActionView/Helpers/FormTagHelper/… Commented Aug 2, 2017 at 14:37
  • One other thing, do you think that a radio button is correct for this functionality? A select dropdown would not be better? Commented Aug 2, 2017 at 14:40
  • Hi @GabrielMesquita no I haven't used the radio_button_Tag... I'm not sure what is correct for this functionality, maybe the select dropdown would be better. I'm getting kind of lost in this all :) Could you post how you would do this?? Commented Aug 2, 2017 at 14:46
  • Ok I will try.. Commented Aug 2, 2017 at 14:47
  • 1
    I strongly recommend you to use a column delivery_type (string) instead of pick_up (bool) for flexibility reasons. Then you can ensure the presence of this delivery_type attribute with a validates and also make sure the value is valid (use a constant as whitelist). Then in the Admin pages, you can just display the delivery_type and the address when relevant. Commented Aug 2, 2017 at 15:29

1 Answer 1

2

So you want to know if the product is going to be picked up at the store or sent by email correct?

Since you are lost, a simpler solution would be:

1 - Change the t.boolean "pick_up" to t.string "pick_up"

2 - use this http://guides.rubyonrails.org/form_helpers.html#the-select-and-option-tags, to create a list with this two options.

3 - In your controller save the option the user wants.

I think that in order to use radio buttons, you must have two fields in your database. Something like this:

t.boolean "pick_up" t.boolean "sent_email"

if the user choose to pick up, you will receive a param with a true value for pick up, then you can save on you database. So this is another option too!

Hope it helps.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks @GabrielMesquita, I'm not sure why I should change the t.boolean to string since boolean is either true or false. The database will see either true = sent product or false = pick up products.
@codegirl a boolean type is, like you said, true or false (or nil but that should be handled by your code/DB). What if tomorrow your boss wants you to add another type of delivery, let's say pigeons? You would have to convert this boolean column to string type and update the existing data depending on its current value, etc. See where I am going? You are currently implementing a feature that can potentially become something bigger, try to produce a flexible code/DB structure right now so you won't have to spent a lot of effort if that eventuality comes.
Like @MrYoshiji said, string is more flexible and i think it solves your issue. If the answer helped, please give an upvote :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.