Routing Rails Admin Controller Create Action - ruby-on-rails

A dedicated admin/countries_controller is being correctly used for all actions (index, ...), except for creating records. Here the regular countries_controller from the parent controller directory is active:
Started POST "/countries" for 127.0.0.1 at 2011-06-29 23:26:38 +0200
Processing by CountriesController#create as HTML
What is missing to have the POST action being routed to admin/countries?
routes.rb:
resources :countries
namespace :admin do
resources :countries
end
rake routes:
countries GET /countries(.:format) {:action=>"index", :controller=>"countries"}
POST /countries(.:format) {:action=>"create", :controller=>"countries"}
new_country GET /countries/new(.:format) {:action=>"new", :controller=>"countries"}
admin_countries GET /admin/countries(.:format) {:action=>"index", :controller=>"admin/countries"}
POST /admin/countries(.:format) {:action=>"create", :controller=>"admin/countries"}
new_admin_country GET /admin/countries/new(.:format) {:action=>"new", :controller=>"admin/countries"}
Similar question unanswered here:
Rails help with building Admin area - Routing problem

Your form_for needs to be namespaced too:
<%= form_for [:admin, #country] do |f| %>
...
<% end %>
When you pass #country to form_for it's not going to know what namespace you want this form to go to and so it will default to just the standard POST /countries URL.

Related

No route matches {:action=>"show", :controller=>"posts"} missing required keys: [:id]

I'm struggling with this line in the _form: <%= simple_form_for(#post, url: blog_path) do |f| %>, which gives me the error:
No route matches {:action=>"show", :controller=>"posts"} missing required keys: [:id]
Keep in mind that in my routes I have: resources :blog, controller: 'posts', which is to say I am working off of a posts MVC, but I wanted /posts/ to be replaced by /blog/ in the routes.
posts_controller
def new
#post = Post.new
end
def edit
end
The _form works when I go to edit, but not create new.
routes
blog_index GET /blog(.:format) posts#index
POST /blog(.:format) posts#create
new_blog GET /blog/new(.:format) posts#new
edit_blog GET /blog/:id/edit(.:format) posts#edit
blog GET /blog/:id(.:format) posts#show
PATCH /blog/:id(.:format) posts#update
PUT /blog/:id(.:format) posts#update
DELETE /blog/:id(.:format) posts#destroy
model_path by default routing logic in Rails leads to blog#show => /blogs/:id
Change it to blogs_path.
Looking at you routes, I see obvious naming conflict, you must be defined routes wrong.
Be sure it looks like resources :posts, :as=>"blogs", both plural.
UPD
If you want to have only one blog, then resource :post, :as=>"blog", both singular.
But that means one actual input. I'm quite sure you speak of blog/post1, blog/post2, otherwise I can't see any sense in calling it blog?
sorry my english...
<%= simple_form_for(#post, url: blog_path) do |f| %> In this line you are redirecting the form to show (blog_path)
But , depending on the route , the show needs an id (blog GET /blog/:id(.:format)).
You must create a "create" method in the controller that receives the parameters strong ...
There is another method you can use: rails generate scaffold_controller posts
This will build the full CRUD , so you only have to configure the parameters
I hope that helps you
I got best of both worlds this way:
resources :blog, to: 'posts'
resources :posts

How to contruct 'new' in assciated controller in rails 3.1

I have two models in rails 3.1 app: lease_booking and lease_log. Lease_booking has_many lease_logs and lease_log belongs_to lease_booking. In routes.rb the association is:
resources :lease_bookings do
resources :lease_logs
end
In lease_booking show.html.erb, the path to create a new lease log is:
<%= link_to "new Log", new_lease_booking_lease_log_path(#lease_booking) %>
The 'new' code in lease_log controller is:
def new
#lease_log = LeaseBooking.find(params[:id]).lease_log.new()
end
However there is an error for lease_log controller 'new' after clicking 'new log':
Couldn't find LeaseBooking without an ID
It seems that the id (should be 1) of lease booking was not properly recognized in lease log controller.
The lease booking id (1) on the same error page is correct:
Parameters:
{"lease_booking_id"=>"1"}
Is there a way to fix it? Thanks.
UPDATE: Here is the output of rake routes
lease_booking_lease_logs GET /lease_bookings/:lease_booking_id/lease_logs(.:format) {:action=>"index", :controller=>"lease_logs"}
POST /lease_bookings/:lease_booking_id/lease_logs(.:format) {:action=>"create", :controller=>"lease_logs"}
new_lease_booking_lease_log GET /lease_bookings/:lease_booking_id/lease_logs/new(.:format) {:action=>"new", :controller=>"lease_logs"}
edit_lease_booking_lease_log GET /lease_bookings/:lease_booking_id/lease_logs/:id/edit(.:format) {:action=>"edit", :controller=>"lease_logs"}
lease_booking_lease_log GET /lease_bookings/:lease_booking_id/lease_logs/:id(.:format) {:action=>"show", :controller=>"lease_logs"}
PUT /lease_bookings/:lease_booking_id/lease_logs/:id(.:format) {:action=>"update", :controller=>"lease_logs"}
DELETE /lease_bookings/:lease_booking_id/lease_logs/:id(.:format) {:action=>"destroy", :controller=>"lease_logs"}
Your parameter output shows shat param you should be looking for - lease_booking_id :
#lease_log = LeaseBooking.find(params[:lease_booking_id]).lease_log.new()
From the console, run rake routes to see how the nested routes use the parameters.
Edit:
When you nest your routes the inner resources depend on the outer resource:
resources :lease_bookings do
resources :lease_logs
end
Look at the rake routes output for creating your lease_log:
POST /lease_bookings/:lease_booking_id/lease_logs
So when you set up your form you need to specify the lease_booking as well as the new lease_log (and any _path or _url methods will need to be adapted accordingly):
<%= simple_form_for [#lease_booking, #lease_log] do |f| %>
This would also require you to set the #lease_booking in your controller:
See http://guides.rubyonrails.org/routing.html for more information on Rails routing.
def new
#lease_booking = LeaseBooking.find(params[:lease_booking_id])
#lease_log = #lease_booking.lease_log.new
end
Here is a perfect example I found to construct both controller and view for 1-to-many association:
http://jonathanhui.com/ruby-rails-3-model-1-many-association

Route missing on nested route

Not sure why this isn't working. It was working perfectly and then I restarted the server. I am getting a no route error:
No route matches {:action=>"new", :controller=>"issues"}
Here is the helper i am trying to call:
<%= link_to "Add Issue", new_app_issue_path %>
and my routes file:
resources :apps do
resources :issues
end
Why would it break all of a sudden? And I obviously have the route:
app_issues GET /apps/:app_id/issues(.:format) {:action=>"index", :controller=>"issues"}
POST /apps/:app_id/issues(.:format) {:action=>"create", :controller=>"issues"}
new_app_issue GET /apps/:app_id/issues/new(.:format) {:action=>"new", :controller=>"issues"}
You need to specify what app this is for:
new_app_issue_path(an_app_object_or_an_app_objects_id)
Rails would only "guess" this if params[:app_id] was available, which doesn't appear to be the case here.

Ruby on Rails: link_to action, no route matches

I'm getting into Rails and trying to add a "vote" feature on a blog setup from here: http://guides.rubyonrails.org/getting_started.html
In app/controllers/posts_controller.rb I created this:
def incvotes
#post = Post.find(params[:id])
post.update_attributes(:upvotes => 1 )
format.html { redirect_to(#post, :notice => 'Vote counted.') }
format.xml { head :ok }
end
In app/views/posts/index.html.erb I created this:
<%= link_to 'Vote', :controller => "posts", :action => "incvotes", :id => post.id %>
But the link is giving the error
No route matches {:controller=>"posts", :action=>"incvotes", :id=>1}
I'm missing something here, but not sure what.
rake routes:
incvotes_post POST /posts/:id/incvotes(.:format) {:action=>"incvotes", :controller=>"posts"}
posts GET /posts(.:format) {:action=>"index", :controller=>"posts"}
POST /posts(.:format) {:action=>"create", :controller=>"posts"}
new_post GET /posts/new(.:format) {:action=>"new", :controller=>"posts"}
edit_post GET /posts/:id/edit(.:format) {:action=>"edit", :controller=>"posts"}
post GET /posts/:id(.:format) {:action=>"show", :controller=>"posts"}
PUT /posts/:id(.:format) {:action=>"update", :controller=>"posts"}
DELETE /posts/:id(.:format) {:action=>"destroy", :controller=>"posts"}
home_index GET /home/index(.:format) {:action=>"index", :controller=>"home"}
root /(.:format) {:action=>"index", :controller=>"home"}
try
= link_to "vote", incvotes_post_path(post), :method=>:post
and if that doesn't work, try changing the method to :put
My guess is that you probably do not have a definition in your routes file for the action you just defined in the controller. Both an action in the controller and an action in the routes file must be defined for Rails to generate urls correctly.
Your routes file probably has something like this:
resources :posts
But you want to add more than the standard actions generated by the resources keyword, so try something like this:
resources :posts do
member do
post 'incvotes'
end
end
This tells routes that you have another action in your posts controller called incvotes that accepts HTTP post requests as long as they are pointed at a member route with the correct action (/posts/14 is a member route, while /posts/ is a 'collection' route). So you will have a new route probably like /posts/14/incvotes that you can post a form to and everything should start working properly.
EDIT:
Actually I guess since you are just adding 1 to an attribute on a model, you don't need a POST action (which are normally associated with posting forms as with create and update). To send a post, you might need to change the HTML in the view to include a form and have it post to the correct url. So you can try that, or you can change your routes file to read get 'incvotes' instead of post 'incvotes'. Sorry for the confusion, hope that helps!
The incvotes_post route only accepts a HTTP POST, and a link always produces a HTTP GET.
Use a form with a button instead (or do a POST using AJAX).
Try using button_to instead link_to:
In your view:
<%= button_to 'Vote', incvotes_post_path(post) %>
In your config/routes.rb add the route to incvotes action as post:
resources :posts do
member do
post 'incvotes'
end
end
And in your controller, create the incvotes action:
def incvotes
# Something
redirect_to :posts
end

POST request in namespaced resource controller going to index action instead of create

I have a namespaced controller for some admin functionality. My create form does not work -- it ends up routing the request to the index action instead of the create action.
Why isn't the POST getting routed to the create action as it should (being RESTful)?
routes.rb:
map.namespace :admin do |admin|
admin.resources :events
end
rake routes:
admin_events GET /admin/events {:action=>"index", :controller=>"admin/events"}
formatted_admin_events GET /admin/events.:format {:action=>"index", :controller=>"admin/events"}
POST /admin/events {:action=>"create", :controller=>"admin/events"}
POST /admin/events.:format {:action=>"create", :controller=>"admin/events"}
new_admin_event GET /admin/events/new {:action=>"new", :controller=>"admin/events"}
formatted_new_admin_event GET /admin/events/new.:format {:action=>"new", :controller=>"admin/events"}
edit_admin_event GET /admin/events/:id/edit {:action=>"edit", :controller=>"admin/events"}
formatted_edit_admin_event GET /admin/events/:id/edit.:format {:action=>"edit", :controller=>"admin/events"}
admin_event GET /admin/events/:id {:action=>"show", :controller=>"admin/events"}
formatted_admin_event GET /admin/events/:id.:format {:action=>"show", :controller=>"admin/events"}
PUT /admin/events/:id {:action=>"update", :controller=>"admin/events"}
PUT /admin/events/:id.:format {:action=>"update", :controller=>"admin/events"}
DELETE /admin/events/:id {:action=>"destroy", :controller=>"admin/events"}
DELETE /admin/events/:id.:format {:action=>"destroy", :controller=>"admin/events"}
app/views/admin/events/new.html.erb:
<h1>New event</h1>
<% form_for([:admin, #event]) do |f| %>
<%= f.error_messages %>
...
app/controllers/admin/event_controller.rb:
class Admin::EventsController < ApplicationController
def index
#events = Event.find(:all)
...
end
def create
#event = Event.new(params[:event])
...
end
...
end
And finally, a bit of a log file where you can see it is indeed POSTing:
Processing Admin::EventsController#index (for 127.0.0.1 at 2008-10-16 18:12:47) [POST]
Session ID: ...
Parameters: {"commit"=>"Create", "authenticity_token"=>"...", "action"=>"index", "controller"=>"admin/events", "event"=>{"location"=>""}}
Event Load (0.000273) SELECT * FROM `events`
Rendering template within layouts/application
Rendering admin/events/index
Completed in 0.00757 (132 reqs/sec) | Rendering: 0.00118 (15%) | DB: 0.00027 (3%) | 200 OK [http://localhost/admin/events]
The order of the routes was the issue. I'm not sure exactly why, but moving it below my root routes (map.connect '') solves the issue, and Rails routes the requests accordingly.

Resources