Undefined method with "_path" while using rails form_for - ruby-on-rails

I'm running into a (I think) routing error while using the Rails form_for helper. I have been searching around and looked at this question, but the plural for "static_event" with pluralize is "static_events" so I am at a loss. Any help would be apprecited. Here are the details....
ActionView::Template::Error (undefined method `static_events_path' for #<#<Class:0x007f9fcc48a918>:0x007f9fcc46fa78>):
My Model:
class StaticEvent < ActiveRecord::Base
attr_accessible :content, :title, :discount, :location, :day_of_week, :start_time
My Controller:
class StaticEventsController < ApplicationController
before_filter :authenticate, :only => [:create, :destroy]
before_filter :authorized_user, :only => [:destroy]
def new
#title = "Share An Event"
#static_event = StaticEvent.new
end
def create
#static_event = current_user.static_events.build(params[:event])
if #static_event.save
flash[:success] = "Event Shared"
redirect_to #static_event #this was the old version
else
render :new
end
end
The route:
match '/static-events/new', :to => 'static_events#new'
match '/static-events/', :to => 'static_events#index'
match '/static-events/:id', :to => 'static_events#show'
The view
<%= form_for (#static_event) do |f| %>
<%= render 'shared/error_messages', :object => f.object %>
<%= text_field "static_event", "title", "size" => 48 %>
<%= time_select "static_event", "start_time", {:ampm => true, :minute_step => 15} %>
<%= text_area "static_event", "content", "cols" => 42, "rows" => 5 %>
<%= text_field "static_event", "discount", "size" => 48 %>
<%= text_field "static_event", "location", "size" => 48 %>
<%= text_field "static_event", "day_of_week", "size" => 48 %>
<input name="" type="submit" class="button" value="share on chalkboard" />
<% end %>

Only routes created using the resources method are automatically named.
If you want to name your routes, use the :as option:
match '/static-events/new', :to => 'static_events#new', :as => :new_static_event
match '/static-events/', :to => 'static_events#index', :as => :static_events
match '/static-events/:id', :to => 'static_events#show', :as => :static_event
However, it's better to use the resources method. You must pass the "true" name of your model as the first parameter, then override the path if you want:
resources :static_events, :path => 'static-events'

First of all, you should define your routes this way:
resources 'static-events', :only => [:new, :create]
This will create a route for new and create methods.
Because when you use a new ActiveRecord object as an argument to form for, it will looks for *s_path like static_events_path in your routes file with the POST verb.
I think the way you have defined your routes doesn't create the static_events_path with POST verb (you can check that by using rake routes as megas said). So don't use match anymore, use resources or get/post/... instead of match in your Rails 3 projects.
EDIT
I did not notice yesterday, but there is no route for create method. Add the route below before static_events#index or remove all your routes and do like I said above.
post '/static-events/', :to => 'static_events#create'

Run rake routes and you'll see the list of your routes. Then you can fix the route file to have appropriate route path.

This happened to me when i was using a nested resource, but forgot to actually initialize the parent resource using load_and_authorize_resource in cancan. Therefore, the parent resource was null and it threw this error.
I fixed it by declaring load_and_authorize_resource on the parent in the controller.

Related

Couldn't find User with id=search

I want to a searching function for users. It does not work. So I simplified the method, I just want to refresh the index page when I hit the search button. But it still does not work, it said
ActiveRecord::RecordNotFound in UsersController#show, Couldn't find User with id=search.
please tell me Why
my controller
class UsersController < ApplicationController
load_and_authorize_resource :except => [:index]
def search
redirect_to users_path
end
end
My view
<%= form_tag users_search_path, :method => 'get' do %>
<td><%= text_field_tag :username, params[:username] %></td>
<%= submit_tag "Search", :class => "buttons buttons-rounded buttons-flat-action", :id => "button-new"%>
<br><br><br>
<% end %>
My Route
Procedures::Application.routes.draw do
devise_for :users
#### USER MANAGEMENT ####
resources :users do
resources :rateofpays # professional timesheet
resources :roles
resources :biographies
resources :qualifications do
collection do
put 'complete', :action => 'complete'
end
end
resources :supervisors
end
#### users search ####
get 'users/search' => "users#search", as: 'users_search'
The line
get 'users/search' => "users#search", as: 'users_search'
...is too far down in your routes. the resources :users appears first, and it has a match path that looks like users/:id and the users/search is incorrectly matching against that.
Just move the get 'users/search' to the top... or alternatively define it as a collection method under resources :users
resources :users do
collection do
get 'search'
end

Couldn't find [model] without an ID - Ruby on rails

I have multiples forms in the Edit view like you can see below:
View
-#posts.each do |post|
.form
= simple_form_for post, url: update_posts_path do |f|
= f.input :title
= f.submit
Then when I'm updating any form I get this error 'Couldn't find Pots without an ID'. You can see the controller and the routes file here:
Controller
def update
#post = Posts.find(params[:id]) //If I change it for Posts.first then is working
if #post.update_attributes(params.require(:posts).permit(:title))
redirect_to ....
else
flash[:notice] = "Sorry."
render :edit
end
end
Routes File
resources :posts, :only => [:index, :edit, :update] do
get "edit", :on => :collection, :as => :edit
patch "update", :on => :collection, :as => :update
end
I think that the error is that for some reason this (#post = Posts.find(params[:id])) is returning a nil object then the controller can't update it. Can someone give me a hand?
The error is the :on => :collection part. This allows the action to be called without an id, so params[:id] is empty.
:on => :collection is normally used for index like actions that have a set of records as a result, so don't need the id part.
btw: the whole thing:
get "edit", :on => :collection, :as => :edit
patch "update", :on => :collection, :as => :update
is redundant, the first line:
resources :posts, :only => [:index, :edit, :update]
tells Rails everything it needs.
For update action you are using :on => :collection but your request is put/patch request so you will use patch "update", :on => :member, :as => :update also make changes in form_for as per your route.Use<%=simple_form_for post ,:url=> update_post_path(post) do |f| %> instead of url: update_posts_path
Regarding params.require(:posts).permit(:title)
First problem : you are using posts instead of post
second is Parameter :id is missing
you will use params.require(:post).permit(:title,:id) instead of params.require(:posts).permit(:title)

Rails: form for different controller

I'm developing a rails app with a landingpage. On the landingpage, the user can sign up for the app. For login, there is an extra view with an extra controller.
It looks like this:
views/landinpage/index.html --> sign up form
views/login/index.html --> login form
but I only want to have one controller
controllers/login_controller --> create new user from sign up form & check login data
so I have to get a connection between the landingpage view and the login_controller.
This is my attempt:
<%= form_for #login, :url => { :controller => "login_controller", :action => "create" }, :html => {:method => :post} do |f| %>
but it throws a route error:
No route matches {:controller=>"login_controller", :action=>"create"}
I already defined login resources in routes.rb, but it seems that the problem is elsewhere?
resources :logins
any ideas?
try this
class LoginsController < ApplicationController
def new
...
end
def create
...
end
...
end
in your route.rb file write
match '/login/create' => 'logins#create', :as => :create_login
or
resources :logins
in your console - write - rake routes and check your routes
then
<%= form_for #login, :url => create_login_path(#login) do |f| %>
I think your code should look like this:
<%= form_for #login, :url => { :controller => "login", :action => "create" }, :html => {:method => :post} do |f| %>
can't test this right now, but I believe the _controller part is not required.
Update:
Another thing that I'm using a lot and that works:
<%= form_for #login, :url => create_login_path(#login), :html => {:method => :post} do |f| %>
You may have to fix the create_login_path part to match your application's routes but that's how I usually define these views.
Try this
class LoginsController < ApplicationController
def new
...
end
def create
...
end
...
end
in your routes.rb file
resources :logins do
collection do
post :create
end
end
and in your views
<%= form_for #login, :url => create_login_path(#login) do |f| %>>
you can see the html form action part, you can see!
your config/routes has
resources :posts
namespace :admin do
resources :posts
end

Rails 3 : Can't get form_for to work as a 'delete' following the RESTful achitecture => always giving a ROUTING ERROR

I have a very simple render that goes as follow:
<%= form_for(:relationships, :url => relationships_path, :html => {:method => 'delete'}) do |f| %>
<div><%= f.hidden_field :user_id_to_unfollow, :value => #user.id %></div>
<div class="actions"><%= f.submit "Unfollow" %></div>
<% end %>
When I submit this form it will always give me a
Routing Error
No route matches "/relationships"
on my page.
In my relationships controller, I have created all the propers methods:
def create
...
end
def destroy
...
end
def update
...
end
def show
...
end
And in my routes config I have made sure to allow all routes for the relationships controller
resources :relationships
But I can't seem to get into the destroy method of the controller :(
However if I remove the
:html => {:method => 'delete'}
method parameter in the form_for then I get to the create method of the controller no pb.
I don't get it....
Alex
ps: this is the rake routes results for relationships:
relationships GET /relationships(.:format) {:action=>"index", :controller=>"relationships"}
POST /relationships(.:format) {:action=>"create", :controller=>"relationships"}
You should point the delete request to single resource url eg. relationships/4325. Run rake routes to view what url/verb combinations are valid.
--edit
Routes for relationship resources:
resources :relationships, :only => [:index, :create, :destroy]
Unfollow button (creates a form for itself):
= button_to "Unfollow", relationship_path(relationship), :method => 'delete'

Rails3 nested-routing issues

I would like to create a mechanism for a User to keep track of other, favorite Users, similar to SO's favorite questions. I'm using the Rails 3.0 beta.
To do so, I have a User-Favorite HABTM relationship, which works as expected:
class User < ActiveRecord::Base
has_and_belongs_to_many :favorites, :class_name => "User", :join_table => "favorites", :association_foreign_key => "favorite_id", :foreign_key => "user_id"
end
The Favorites Controller only needs 3 of the 7 RESTful methods to manage a User's favorites:
class FavoritesController < ApplicationController
# GET /favorites
# GET /favorites.xml
def index
#user = User.find(params[:user_id])
#favorites = #user.favorites.joins(:profile).order("last_name,first_name")
...
end
def create
#favorite = User.find(params[:id])
current_user.favorites << #favorite
...
end
def destroy
#favorite = User.find(params[:id])
current_user.favorites.delete(#favorite)
...
end
end
The Routes.rb file contains the routing instruction:
resources :users, :except => :destroy do
resources :favorites, :only => [:index,:create,:destroy]
end
that generates these user-favorite routes:
GET /users/:user_id/favorites(.:format) {:controller=>"favorites", :action=>"index"}
user_favorites POST /users/:user_id/favorites(.:format) {:controller=>"favorites", :action=>"create"}
user_favorite DELETE /users/:user_id/favorites/:id(.:format) {:controller=>"favorites", :action=>"destroy"}
In the User's Show View, the User (#user) can be toggled as a favorite using image links, which works as expected:
<% if [test if user is a favorite] %>
# http://localhost:3000/favorites/destroy/:id?post=true
<%= link_to image_tag("favorite.png", :border => 0), :controller => :favorites, :action => :destroy, :post=>true, :id => #user %>
<% else %>
# http://localhost:3000/favorites/create/:id?post=true
<%= link_to image_tag("not-favorite.png", :border => 0), :controller => :favorites, :action => :create, :post=>true, :id => #user %>
<% end %>
However, in the current_user's favorite Index View, the link_to each favorite user:
# http://localhost:3010/users/4/favorites/3?post=true
<%= link_to image_tag("favorite.png", :border => 0), :controller => :favorites, :action => :destroy, :id => favorite, :post=>true %>
generates an error that reads:
No route matches "/users/4/favorites/3"
Questions:
Have I correctly specified my routing? Seem like the create and destroy routes would only need the id of the favorite, as the 'owner' of the favorite is always current_user.
If I'm simply referencing the Controller/Action in the Show view, do I even need the create/destroy routes?
Why doesn't the link_to in the Index View work correctly?
Are there any improvements that can be made to the over-all approach?
Your routing looks fine.
I think there is something wrong with your link_to, though. For one thing, the RESTful way is not to specify URLs with :controller and :action parameters. The correct way is using the generated URL methods, such as user_favorite_path. Also, you need to specify the :method parameter when targeting the destroy action. This is how I think the link_to should look like:
<%= link_to image_tag("favorite.png", :border => 0), user_favorite_path(#user, #favorite), :method => :delete %>
I believe the reason it says no route matches that URL is because you didn't specify the :method as :delete.
in your rake routes output, the paramater needed is :user_id not :id, so you need to send that in your link_to call.

Resources