Reputation: 141
trying to setup a page so users can place an order when they sign in..
if you type in /listings/27/orders/new this will go to a new order form so you can order item 27. But when i fill in the address details and create an order I get error..NoMethodError in OrdersController#create..undefined method `order_url' for #
OrdersController#create
class OrdersController < ApplicationController
before_action :set_order, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
# GET /orders
# GET /orders.json
def index
@orders = Order.all
end
# GET /orders/1
# GET /orders/1.json
def show
end
# GET /orders/new
def new
@order = Order.new
@listing = Listing.find(params[:listing_id])
end
# GET /orders/1/edit
def edit
end
# POST /orders
# POST /orders.json
def create
@order = Order.new(order_params)
@listing = Listing.find(params[:listing_id])
@seller = @listing.user
@order.listing_id = @listing.id
@order.buyer_id = current_user.id
@order.seller_id = @seller.id
respond_to do |format|
if @order.save
# ERROR on the following line!!
format.html { redirect_to @order, notice: 'Order was successfully created.' }
format.json { render action: 'show', status: :created, location: @order }
else
format.html { render action: 'new' }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /orders/1
# PATCH/PUT /orders/1.json
def update
respond_to do |format|
if @order.update(order_params)
format.html { redirect_to @order, notice: 'Order was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
# DELETE /orders/1
# DELETE /orders/1.json
def destroy
@order.destroy
respond_to do |format|
format.html { redirect_to orders_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order
@order = Order.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_params
params.require(:order).permit(:delivery_address, :delivery_city, :delivery_state)
end
end
listing.db
class Listing < ActiveRecord::Base
if Rails.env.development?
has_attached_file :image, :styles => { :medium => "200x", :thumb => "100x100>" }, :default_url => "photo.jpg"
else
has_attached_file :image, :styles => { :medium => "200x", :thumb => "100x100>" }, :default_url => "photo.jpg",
:storage => :dropbox,
:dropbox_credentials => Rails.root.join("config/dropbox.yml"),
:path => ":style/id_:filename"
end
validates :name, :description, :price, presence: true
validates :price, numericality: { greater_than: 0 }
validates_attachment_presence :image
belongs_to :user
has_many :orders
end
order.rb
class Order < ActiveRecord::Base
validates :delivery_address, :delivery_city, :delivery_state, presence: true
belongs_to :listing
belongs_to :buyer, class_name: "User"
belongs_to :seller, class_name: "User"
end
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
validates :name, presence: true
has_many :listings, dependT.nt: :destroy
has_many :sales, class_name: "Order", foreign_key: "seller_id"
has_many :purchases, class_name: "Order", foreign_key: "buyer_id"
end
rake routes
devise_for :users
resources :listings do
resources :orders
end
get "pages/about"
get "pages/contact"
get 'seller' => "listings#seller"
root 'listings#index'
Upvotes: 0
Views: 382
Reputation: 4636
I believe you're redirecting to a variable, while you should redirect to a URL present in you routes file.
I think it should be:
# ...
respond_to do |format|
if @order.save
format.html { listing_order_url(@listing, @order), notice: 'Order was successfully created.' }
format.json { render action: 'show', status: :created, location: @order }
else
format.html { render action: 'new' }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
Upvotes: 0
Reputation: 53038
As per the nested routes,
devise_for :users
resources :listings do
resources :orders
end
order_url doesn't exist, redirecting to @order
will make rails look for a path order_url
.
Do rake routes
and check the available paths(look at the prefix
column).
Use
redirect_to listing_order_url(@listing,@order)
instead of
redirect_to @order
in both create
and update
actions of OrdersController
.
Also, update destroy
action as below
def destroy
@order.destroy
respond_to do |format|
format.html { redirect_to listing_orders_url(@order.listing) } ## orders_url doesn't exist, use listing_orders_url
format.json { head :no_content }
end
end
Upvotes: 1
Reputation: 2175
You are using nested resources. You should change the redirect to use a nested resource url, in this case to:
redirect_to listing_order_url(@listing, @order), notice: 'Your order has been created'
According to Rails Guides, if it's a link_to
you could use this other format:
link_to 'Order Details', [@listing, @order]
Upvotes: 0