1
votes

We're developing a social network prototype with Ruby on Rails 3.2. The system is made for travellers, so each user necessarily has many trips. We created the trip model and we set the associations with "belongs_to" and "has_many", respectively in the trip model and in the user model. We created a form to create a new trip for a specific user, but when we submit the form the system returns this error:

Routing Error
No route matches {:action=>"show", :controller=>"trips"}

We know that the trip has been created successfully, because if we type the URL http://localhost:3000/users/1/trips/1 we see the created trip.

This is the code:

trip.rb

class Trip < ActiveRecord::Base
  attr_accessible :name, :departure, :arrive, :trip_objects

  belongs_to :user

  default_scope order: 'trips.created_at DESC'
  validates :user_id, presence: true
  validates :name, :departure, :arrive, :trip_objects, presence: true
end

trips_controller.rb

def create
  # refine the trip variable content with the data passed by the sign up form
  @trip = current_user.trips.build(params[:trip])
  if @trip.save
    # handle a successful save
    flash[:success] = 'Trip created!'
    redirect_to user_trip_path
  else
    @trip = []
    redirect_to home_path
  end
end

def index
 @user = User.find(params[:user_id])
 # get all her trips
 @trips = @user.trips.paginate(page: params[:page])
end

into the routes.rb

resources :users do
  member do
     get :info
  end
  resources :trips, only: [:new, :create, :index, :show, :destroy]
end

Furthermore in the trips_controller.rb - create action, if we redirect to user_trips_path instead of user_trip_path we get correctly the index of created trips, accordingly to the routes.

Here you are the routes

    info_user GET    /users/:id/info(.:format)           users#info
   user_trips GET    /users/:user_id/trips(.:format)     trips#index
              POST   /users/:user_id/trips(.:format)     trips#create
new_user_trip GET    /users/:user_id/trips/new(.:format) trips#new
    user_trip GET    /users/:user_id/trips/:id(.:format) trips#show
              DELETE /users/:user_id/trips/:id(.:format) trips#destroy
        users GET    /users(.:format)                    users#index
              POST   /users(.:format)                    users#create
     new_user GET    /users/new(.:format)                users#new
    edit_user GET    /users/:id/edit(.:format)           users#edit
         user GET    /users/:id(.:format)                users#show
              PUT    /users/:id(.:format)                users#update
              DELETE /users/:id(.:format)                users#destroy

Do you have any idea of the problem? We're pretty new to Rails so any help would be appreciated. Thanks a lot!

2
Your life will be a bit easier if trips is not a nested resource. It doesn't need to be nested, not yet.Sergio Tulentsev

2 Answers

3
votes

As you can see user_trip_path requires both an :id and a :user_id.

user_trip GET /users/:user_id/trips/:id(.:format) trips#show

def create
  # refine the trip variable content with the data passed by the sign up form
  @trip = current_user.trips.build(params[:trip])
  if @trip.save
    # handle a successful save
    flash[:success] = 'Trip created!'
    redirect_to user_trip_path(id: @trip, user_id: @user)
  else
    @trip = []
    redirect_to home_path
  end
end

Another way to solve this is to use shallow nesting:

resources :users, shallow: true do
  resources :trips
end

Which gives you the collection routes (new, create, index) for trips nested under user but not the individual routes (show, edit, destroy).

That lets you do redirect_to @trip instead.

0
votes

The problem is this line redirect_to user_trip_path in your create method. It should be redirect_to user_trip_path(@trip, user_id: current_user.id)

As you can see in rake routes output,

user_trip GET    /users/:user_id/trips/:id(.:format) trips#show

You have to pass :user_id and :id for the route.