Marko I. Marko I. - 5 months ago 21
Ruby Question

How associate order with a current_user?

I'm building a store that has items and orders for each user.
Right now I want to associate each order with a current_user. That is, the one that is making an order.
I figured how to associate models but I can't figure out what to write that will save user_id to order model upon the creation of an order. I'm using standard Devise engine.

These are my models:

Order.rb

belongs_to :order_status
belongs_to :user
has_many :order_items
before_create :set_order_status
before_save :update_subtotal

def subtotal
order_items.collect { |oi| oi.valid? ? (oi.quantity * oi.unit_price) : 0 }.sum
end
private
def set_order_status
self.order_status_id = 1
end

def update_subtotal
self[:subtotal] = subtotal
end
end


order_item.rb

class OrderItem < ActiveRecord::Base
belongs_to :product
belongs_to :order

validates :quantity, presence: true, numericality: { only_integer: true, greater_than: 0 }
validate :product_present
validate :order_present

before_save :finalize

def unit_price
if persisted?
self[:unit_price]
else
product.price
end
end

def total_price
unit_price * quantity
end

private
def product_present
if product.nil?
errors.add(:product, "is not valid or is not active.")
end
end

def order_present
if order.nil?
errors.add(:order, "is not a valid order.")
end
end

def finalize
self[:unit_price] = unit_price
self[:total_price] = quantity * self[:unit_price]
end
end


And in the user.rb I have:
has_one :order


This is my OrderItemsController:

class OrderItemsController < ApplicationController
def create
@order = current_order
@order_item = @order.order_items.new(order_item_params)
@order.save
session[:order_id] = @order.id
end

def update
@order = current_order
@order_item = @order.order_items.find(params[:id])
@order_item.update_attributes(order_item_params)
@order_items = @order.order_items
end

def destroy
@order = current_order
@order_item = @order.order_items.find(params[:id])
@order_item.destroy
@order_items = @order.order_items
end
private
def order_item_params
params.require(:order_item).permit(:quantity, :product_id)
end
end

Answer

Couple ways to go about associating a user with an order. A user should have many orders. First, have you written a migration to add a user_id column to your orders table? Create one by reference: rails g migration AddUserToOrder user:references

Then update your permitted params for order to permit user_id.

From there you have the option of doing a few things...you could set the user_id in the create action of your orders controller before saving. (related but not your Q--you're going to need an order_id for an order_item, no?) Alternatively, you could pass the user_id in your form via a hidden field.

Either of those will associate it for you.

Comments