No route matches [POST] in Ruby app I'm building - ruby-on-rails

I'm trying to build an application that lets users create a trip with restful routing however, I'm encountering an issue when a user is logged in and they try to create a trip.
I get "No route matches [POST] "/users/8/trips/new""
These are the routes:
resources :users do
resources :trips
end
This is the trip controller:
class TripsController < ApplicationController
def new
#trip = Trip.new
end
def create
#trip = Trip.create(trip_params)
redirect_to root_path
end
end
This is the form to create a new trip. This is where I click submit and get the error:
<div class="trip_form">
<%= form_for :trip do |f| %>
<%= f.label :where, "Where?" %><br/>
<%= f.text_field :where, placeholder: "Hawaii" %><br>
<%= f.label :when, "When?" %><br/>
<%= f.text_field :when, placeholder: "#" %><br>
<%= f.label :price_per_person, "Price per person? (Approximately)" %><br/>
<%= f.text_field :price_per_person, placeholder: "$550" %><br>
<%= f.submit "Create Trip Idea"%>
<% end %>
These are the routes:
$ rake routes
Prefix Verb URI Pattern Controller#Action
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
edit_user_trip GET /users/:user_id/trips/:id/edit(.:format) trips#edit
user_trip GET /users/:user_id/trips/:id(.:format) trips#show
PATCH /users/:user_id/trips/:id(.:format) trips#update
PUT /users/:user_id/trips/:id(.:format) trips#update
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
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
root GET / users#index
I thought I should be able to just fill out the trip new form and when I press submit for it to
automatically communicate with the create method in the trip controller? When I do change :trip to #trip in the form I get this error:
NoMethodError in Trips#new
undefined method `trips_path'
Thanks!

<%= form_for :trip do |f| %>
should be
<%= form_for [#user, #trip] do |f| %>
and because you're using nested resources you'll need this too
# controller
def new
#user = User.find(1)
#trip = Trip.new
end
More in the documentation for form_for

There is a tiny mistake in your form_for helper. It should be:
<%= form_for #trip do |f| %>
...
The helper will look at the #trip object and see that it is a new object (= not yet saved to the database) and thus will choose POST /users/8/trips as the form action.
By not handing an ActiveRecord Object to the helper, the generated HTML form has no action, so submitting the form will POST to the current path (which is the new-path)
EDIT
In order to let the helper choose a route for the nested resource situation you have, use:
<%= form_for [current_user, #trip] do |f| %>
...
assuming that current_user is the user object you are referring to.

Related

routing error for nested resource with ledermann-rails-settings

I'm trying to allow users to update preferences from default settings with a form for ledermann-rails-settings. I got the form built based on this answer, but when I try to submit the form to update settings, I get a routing error that I think is related to nested resources, but I'm new to RoR so I'm not sure. Other questions about this on SO appear to use Rails 3 or a previous version of the gem. I'm using rails 4.2.1.
routes.rb:
resources :users do
resources :settings
end
rake routes:
user_settings GET /users/:user_id/settings(.:format) settings#index
POST /users/:user_id/settings(.:format) settings#create
new_user_setting GET /users/:user_id/settings/new(.:format) settings#new
edit_user_setting GET /users/:user_id/settings/:id/edit(.:format) settings#edit
user_setting GET /users/:user_id/settings/:id(.:format) settings#show
PATCH /users/:user_id/settings/:id(.:format) settings#update
PUT /users/:user_id/settings/:id(.:format) settings#update
DELETE /users/:user_id/settings/:id(.:format) settings#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
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
the form:
<%= form_for(:settings) do |form| %>
<h3>Dashboard settings</h3>
<%= form.fields_for :dashboard, current_user.settings(:dashboard) do |f| %>
<%= f.label :theme_light, 'Light (Default)' %>
<%= f.radio_button :theme, "themes/flatly" %>
<%= f.label :theme_dark, 'Dark' %>
<%= f.radio_button :theme, "themes/darkly" %>
<% end %>
<%= form.submit "Save" %>
<% end %>
SettingsController:
class SettingsController < ApplicationController
def update
if params[:settings]
params[:settings].each do |key, value|
current_user.settings(key.to_sym).update_attributes! value
end
flash[:success] = "Settings updated!"
redirect_to root_path
else
render 'edit'
end
end
end
User.rb:
has_settings do |s|
s.key :dashboard, :defaults => { :theme => 'themes/flatly' }
end
Submitting the form as-is right now gives the following routing error:
Started POST "/users/1/settings/1/edit" for 72.231.138.82 at 2016-07-01 15:12:36 +0000
ActionController::RoutingError (No route matches [POST] "/users/1/settings/1/edit")
I think I understand the Rails Guides for nested resource forms to mean that the first line of the form should be something like
<%= form_for([#user, #settings]) do |form| %>
but changing that gives the error
First argument in form cannot contain nil or be empty
Additionally, ledermann-rails-settings doesn't appear to have a method for calling all settings (at least so far as I can tell on the current version of the gem), so I'm not sure how I would even define #settings.
I've tried specifying different paths in the form with no luck, as well as trying resource: setting and resources: settings in routes.rb. I feel like I'm missing something at either the controller or routes level, but I don't have enough experience to know where and the gem docs and issues don't have much on forms.
In case it helps someone else, here's how I got this working.
<%= form_for(:settings, url: user_setting_path, html: { method: :put }) do |form| %>
SettingsController
def update
if setting_params
setting_params.each do |key, value|
#current_user.settings(key.to_sym).update_attributes! value
end
flash[:success] = "Settings updated!"
redirect_to request.referrer
else
render 'edit'
end
end
def setting_params
params.require(:settings).permit(dashboard: :theme)
end

Rails form_for wrong controller action

Right out of the Rails Tutorial. I can't get the sign in form to call the create method. Debug shows it only calls the new action. I had no issues setting up the users which also has a database so the following was utilized:
<%= form_for #user do |f| %>
In this case, with no model, I'm doing as the tutorial suggests:
<%= form_for(:session, url: sessions_path) do |f| %>
A quick glance at rake routes shows the route is valid:
Prefix Verb URI Pattern Controller#Action
root GET / site_pages#root
about GET /about(.:format) site_pages#about
signup GET /signup(.:format) users#new
signout DELETE /signout(.:format) sessions#destroy
signin GET /signin(.:format) sessions#new
users POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
user GET /users/:id(.:format) users#show
DELETE /users/:id(.:format) users#destroy
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
session DELETE /sessions/:id(.:format) sessions#destroy
Not sure what I'm missing. Been messing with it for over an hour. Tried changing to form_tag and it's still reacting in the same way. I've edited the routes and the form in multiple ways to trigger the correct functioning with no luck.
What am I missing? Thanks.
Controller added:
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
#SIGN IN AND REDIRECT
else
flash.now[:danger] = "Invalid Submission. Please Try Again."
render 'new'
end
end
<div class="form-horizontal" role="form">
<%= form_for(:session, url: sessions_path) do |f| %>
<%= render 'layouts/flash' %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit "Log In", class: "btn btn-primary btn-width-30" %>
<% end %>
</div>

Edit/Update calls the create in ruby on rails

I am stuck in weird problem. I have few recall values that are created and deleted correctly, but when i try to edit the values and save them, it created new recall.
here is my controller for Edit/update
def edit
#recall = Recall.find(params[:id])
end
def update
#recall = Recall.find(params[:id])
if #recall.update_attributes(params[:recall])
# Handle a successful update.
flash[:success] = "Recall updated"
redirect_to '/recalls'
else
render 'edit'
end
end
def show
#user = Recall.find(params[:id])
end
my edit.html.erb is as follows
<%= form_for(#recall) do |f| %>
<%= f.label :Category, "Category" %>
<div class="control-group">
<div class="controls">
<%= f.select :Category,options_for_select(["Consumer Products",
"Foods, Medicines, Cosmetics",
"Meat and Poultry Products",
"Motor Vehicles",
"Child Safety Seats",
"Tires",
"Vehicle Emissions",
"Environmental Products",
"Boats and Boating Safety"]), {:style => "height:40px"} %>
</div>
</div>
<div class="form-inline">
<%= f.label :Title, "Title" %>
</div>
<%= f.text_field :Title %>
<div class="form-inline">
<%= f.label :Summary, "Summary" %>
</div>
<%= f.text_field :Summary %>
<div class="form-inline">
<%= f.label :Details, "Details" %>
</div>
<%= f.password_field :Details %>
<%= f.submit "Save changes", class: "btn btn-large btn-primary" %>
<% end %>
please let me know where i did wrong. i tried to define :action => 'edit' but it didn't worked out.
Thanks in advance
EDIT
rake routes output is here
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
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
session DELETE /sessions/:id(.:format) sessions#destroy
root / administrator_pages#home
signup /signup(.:format) users#new
signin /signin(.:format) sessions#new
signout DELETE /signout(.:format) sessions#destroy
about /about(.:format) administrator_pages#about
recalls /recalls(.:format) administrator_pages#Recalls
recall /recall(.:format) administrator_pages#create
destroy /destroy(.:format) administrator_pages#destroy
edit /edit(.:format) administrator_pages#edit
users_new GET /users/new(.:format) users#new
paid_user_paid GET /paid_user/paid(.:format) paid_user#paid
basic_user_basic GET /basic_user/basic(.:format) basic_user#basic
search_Search GET /search/Search(.:format) search#Search
here is my routes.rb, looking at rake routes and my routes.rb i can see something wrong. but unable to firgure out the problem
resources :users
resources :sessions, only: [:new, :create, :destroy]
root to: 'administrator_pages#home'
match '/signup', to: 'users#new'
match '/signin', to: 'sessions#new'
match '/signout', to: 'sessions#destroy', via: :delete
match '/about', to: 'administrator_pages#about'
match '/recalls', to: 'administrator_pages#Recalls'
match 'recall', to:'administrator_pages#create'
match 'destroy', to: 'administrator_pages#destroy'
match 'edit', to: 'administrator_pages#edit'
# get "administrator_pages/Recalls"
get "users/new"
get "paid_user/paid"
get "basic_user/basic"
get "search/Search"
I'm not seeing an update method on your routes, just add to your routes.rb
(if an update method on administrator_pages_controller.rb)
match '/recalls', to: 'administrator_pages#recalls', :as => :recalls
match '/edit/:id', to: 'administrator_pages#edit', :as => :edit_recall
put '/update/:id', to: 'administrator_pages#update'm :as => :update_recall
And run rake routes and you will see looks like
recalls GET /recalls administrator_pages#recalls
edit_recall GET /edit/:id(.:format) administrator_pages#edit
update_recall PUT /update/:id(.:format) administrator_pages#update
http://localhost:3000/recalls recalls action
http://localhost:3000/edit/:id edit action
http://localhost:3000/update/:id update action
Your form edit looks like :
<%= form_for(#recall, :url => update_recall_path(#recall), :html => { :method => :put }) do |f| %>
:url => update_recall_path(#recall) for call update action and using :html => { :method => :put }
Your controller update method
def update
#recall = Recall.find(params[:id])
if #recall.update_attributes(params[:recall])
# Handle a successful update.
flash[:success] = "Recall updated"
redirect_to recalls_path
else
render 'edit'
end
end
recalls_path is after update will redirect into http://localhost:3000/recalls
I have try it on my localhost like your code and it's works. Hope this help.
Started PUT "/update/1" for 127.0.0.1 at 2013-07-02 20:37:14 +0700
Processing by AdministratorPagesController#update as HTML
Parameters: {"utf8"=>"V", "authenticity_token"=>"s0tVbNt0JedecA+iCVlJ9GmIhGCsf
ltTbb1ep+mZmcY=", "recall"=>{"name"=>"test"}, "commit"=>"Update Recall", "id"=>"1"
}
←[1m←[36mRecall Load (0.0ms)←[0m ←[1mSELECT "recalls".* FROM "recalls" WHERE "recalls"."id" = ? LIMIT 1←[0m [["id", "1"]]
←[1m←[35m (0.0ms)←[0m begin transaction
←[1m←[36m (1.0ms)←[0m ←[1mUPDATE "recalls" SET "name" = 'test', "updated_at" =
'2013-07-02 20:37:14.772915' WHERE "recalls"."id" = 1←[0m
←[1m←[35m (6.0ms)←[0m commit transaction
Redirected to http://localhost:3000/recalls
Completed 302 Found in 13ms (ActiveRecord: 7.0ms)
you need to send an id of a recallwithin your route, because in edit/update actions you do:
#recall = Recall.find(params[:id])
your route for edit should look like this:
match 'edit/:id', to: 'administrator_pages#edit', as: 'edit_recall'
and looks like you'll need one more for update but with method: :put
with the above route you'll have a url like this:
localhost:3000/3/edit #3 is the id of recall
but if you want administrator_pages ahead you'll have to modify your routes:
match 'administrator_pages/recall/edit/:id', to: 'administrator_pages#edit', as: 'edit_recall'
result:
localhost:3000/administrator_pages/recall/3/edit
at the request params of id will be sent and you can use that Recall.find(params[:id]) in your controller. And you'll have to draw a route for update action too with method put
A better solution, I would add resource recalls to routes:
resources :recalls
this would give me all needed routes to work with recall, edit, new, show, etc..
Try the following code
<%= form_for(#recall, :url => recall_path(#recall), :method => 'PUT') do |f| %>

Rails: Routing error when rendering AJAX partial

I am encountering a routing error when I try to render a partial in an ajax call:
Routing Error
No route matches {:action=>"destroy", :controller=>"relationships", :user_id=>#<User id: 2, username: .....
Within my app, I have a list of followers for a user displayed on the profile page. Instead of paginating the followers, I would like to try to return the next offset of followers from the server through AJAX. My view already utilizes partials for displaying a list of these followers (limited to 5 records).
My goal is to use an AJAX call to return this partial with the next offset of records formated (I haven't implemented the functionality to return offset records yet - I'm just trying to get the ajax working first). The partials work fine when I visit the profile page in my browser (and view the first 5 records), the error occurs when I make the AJAX call.
Here is the form in the view where the ajax call originates:
<%= form_tag user_relationships_path(#user), method: :get, remote: true do %>
<%= submit_tag 'load more...' %>
<% end %>
Here is the route:
resources :users, only: [:index, :show, :new, :create, :edit, :update, :destroy] do
resources :relationships, only: [:create, :destroy, :index]
end
Here is my controller action (relationships#index) which responds to the request:
def index
#user = User.find_by_username(params[:user_id])
respond_to do |format|
format.js { render 'load_followers' }
end
end
The load_followers.js.erb partial:
$('ul#followers').append("<%= render 'users/following_items', users: #user.followers %>")
The users/following_items.html.erb partial:
<% users.each do |user| %>
<li class="clearfix">
<div class="box-gravatar pull-left">
<%= link_to user do %>
<%= gravatar_for user, 40 %>
<% end %>
</div>
<div class="pull-right">
<%= render 'relationships/follow', user: user %>
</div>
<%= link_to user.username, user %>
<div class="box-author">joined <%= join_date_for user %></div>
</li>
<% end %>
And finally the relationships/follow.html.erb partial:
<% unless current_user?(user) %>
<% if current_user.following? user %>
<p><%= link_to 'unfollow', user_relationship_path(user), method: :delete, class: "btn" %></p>
<% else %>
<p><%= link_to 'follow', user_relationships_path(user), method: :post, class: "btn btn-primary" %></p>
<% end %>
<% end %>
I have tracked down the offending code to the relationships/follow.html.erb partial. When that is removed, the ajax call works fine and the partial is appended to the end of the ul. Clearly it has to do with rails having an issue with the link_to to the relationships#destroy method - however, nothing I've tried seems to work.
Edit: Here are the results of running rake routes:
root / posts#index
posts_test /posts/test(.:format) posts#test
submit /submit(.:format) posts#new
signup /signup(.:format) users#new
login /login(.:format) sessions#new
logout DELETE /logout(.:format) sessions#destroy
about /about(.:format) about#index
search /search(.:format) search#index
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
session DELETE /sessions/:id(.:format) sessions#destroy
post_comments POST /posts/:post_id/comments(.:format) comments#create
post_votes POST /posts/:post_id/votes(.:format) votes#create
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
post GET /posts/:id(.:format) posts#show
user_relationships GET /users/:user_id/relationships(.:format) relationships#index
POST /users/:user_id/relationships(.:format) relationships#create
new_user_relationship GET /users/:user_id/relationships/new(.:format) relationships#new
edit_user_relationship GET /users/:user_id/relationships/:id/edit(.:format) relationships#edit
user_relationship GET /users/:user_id/relationships/:id(.:format) relationships#show
PUT /users/:user_id/relationships/:id(.:format) relationships#update
DELETE /users/:user_id/relationships/:id(.:format) relationships#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
categories GET /categories(.:format) categories#index
POST /categories(.:format) categories#create
new_category GET /categories/new(.:format) categories#new
category GET /categories/:id(.:format) categories#show
/:category(.:format) posts#index
Thanks!
Notices your rake routes outputted this line:
DELETE /users/:user_id/relationships/:id(.:format)
This means your named route user_relationship is expecting both user and relationship IDs. Reason being, relationship is a nested resource of user.
So for instance you currently have this in your link to:
= link_to 'unfollow', user_relationship_path(user), method: :delete, class: "btn"
Instead it should be something like:
= link_to 'unfollow', user_relationship_path(user, relationship), method: :delete, class: "btn"

Route failing using STI

First SO post, but I've read so many. I'm new to Rails and building first site since studying Hartl's RailsTutorial.
My issue is routing using STI. I believe the routes are set up correctly, but the subclass Kid doesn't find a "show" route.
Class inheritance using STI
class User < ActiveRecord::Base
class Kid < User
Kid Controller
def show
#kid = Kid.find(params[:id])
end
User Controller create
def create
#user = User.new(params[:user])
if #user.save
flash[:success] = "Welcome to kidtunes!"
if (#user.type = "Kid")
***redirect_to #kid***
else
redirect_to #parent
end
else
render 'new'
end
routes.rb
resources :users, :kids, :parents
root to: 'static_pages#home'
match '/help', to: 'static_pages#help'
match '/contact', to: 'static_pages#contact'
match '/signup', to: 'users#new'
Results in:
kids_new GET /kids/new(.:format) kids#new
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
kids GET /kids(.:format) kids#index
POST /kids(.:format) kids#create
new_kid GET /kids/new(.:format) kids#new
edit_kid GET /kids/:id/edit(.:format) kids#edit
kid GET /kids/:id(.:format) kids#show
PUT /kids/:id(.:format) kids#update
DELETE /kids/:id(.:format) kids#destroy
parents GET /parents(.:format) parents#index
POST /parents(.:format) parents#create
new_parent GET /parents/new(.:format) parents#new
edit_parent GET /parents/:id/edit(.:format) parents#edit
parent GET /parents/:id(.:format) parents#show
PUT /parents/:id(.:format) parents#update
DELETE /parents/:id(.:format) parents#destroy
root / static_pages#home
help /help(.:format) static_pages#help
contact /contact(.:format) static_pages#contact
signup /signup(.:format) users#new
Error
I get the following on redirect_to #kid
ActionController::ActionControllerError (Cannot redirect to nil!):
app/controllers/users_controller.rb:16:in `create'
I feel like I've checked everything I can check, but I'm still missing something. #kid should properly redirect to the kids#show route. I'm not sure if I have a poorly crafted single table inheritance or a basic routing issue.
thanks in advance.
-John
Form
This form is used in users/new.html.erb and it creates the User.
<div class="row">
<div class="span5 offset2">
<%= form_for(#user) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :fname, "First Name" %>
<%= f.text_field :fname %>
<%= f.label :lname, "Last Name" %>
<%= f.text_field :lname %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :type, "Are you a Kid or Parent?" %>
<%= f.select :type, [['Kid','Kid'],['Parent','Parent']] %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation %>
<%= f.submit "Create my account", class: "btn btn-large btn-primary" %>
<% end %>
Have you defined/assigned values to the #kid or #parent variables? If not, they will be nil, and you'll get the cannot redirect to nil error you've included in your question.
Please include the full code for the create action. Otherwise we're left to trust (rather than read for ourselves) precisely what's happening in the redirect.
Your redirects might also need some work. For example, you could do:
if (#user.is_a? Kid)
redirect_to kid_path(#user)
else
redirect_to parent_path(#user)
end
...or something very similar to that.
First thing I noticed is that you're using = instead of ==:
if (#user.type = "Kid")
I think it's nicer to test it like that:
if #user.is_a? Kid
Can you show us how you set #kid and #parent?

Resources