Overwriting rails URL helper (form_for) - ruby-on-rails

I am trying to override a url helper that is being called from a form_for.
My controllers and models are all namespaced in the "Admin" module, and are resting in an admin folder. (So models/admin/foo.rb, controllers/admin/foo_controller.rb)
My routes are correct (I believe)
scope module: "admin" do
resources :foos do
resources :foo_details
end
end
Here is some code to demonstrate what I am attempting to do and where I get the error:
<%= form_for(#foo) do |f| %>
I am getting an error on the form for line, with this: "undefined method `admin_foos_path' for #<#:0x007f08fd7ffb90>.
When I run 'rake routes', I have a route for foos, but not admin_foos. I assume the form_for is trying to access admin_foos_path because of how the application was scaffolded.
Is there a way for me to override admin_foos_path to be foos_path or redirect it? I have tried searching for this issue and haven't been able to come up with much.
Thanks in advance.

Use the namespace directive
namespace :admin do
resources :foos do
resources :foo_details
end
end
Using scope just gives you foos_path, while namespace gives admin_foos_path which is needed for the #foo to work.

undefined method `admin_foos_path' for
To explain the error, #foo is a model instance of Admin::Foo not Foo, so form_for by default look for its resourceful route which in your case it is admin_foos. And because it can't find it, so is the error.
Is there a way for me to override admin_foos_path to be foos_path or
redirect it?
You can overwrite the URL of a form to your desired URL like below
<%= form_for(#foo, url: foos_path) do |f| %>
But I believe you need namespace instead of scope. I recommend to read about when to use scope and namespace in controller-namespaces-and-routing

Related

Rails form builder with admin namespace

The code below works well to create new transactions on the Invoice show view. It however doesn't work when in admin namespace. i.e /admin/invoices/1/ but works on /invoices/1/
show.html.erb
<%= form_for([#invoice, #invoice.transactions.build]) do |form| %>
....
transactions form input
routes.rb
resources :invoices do
resources :transactions
end
When calling form_for in a namespace route like /admin/invoices/1/, Rails will automatically append admin to your route. In other words, form_for([#invoice, #invoice.transactions.build]) would POST to a route like /admin/invoice/:id/transactions/ rather than /invoice/:id/transactions/.
To fix, explicitly set the URL of the form and use a route helper method to infer the correct route:
form_for(#invoice, url: invoice_transaction_url(#invoice.id))
Note that you may need to replace invoice_transaction_url with the correct route. Use rake routes to find the helper method that corresponds to the desired controller POST action.

url helper for namespace nested model

I am using the public_activity gem. To use the gem, you do not need to create an activities controller for it. So I did not. However, I do have a comments controller. I want to have the following url helper for the comment's create action:
public_activity_activity_comments_path(#activity)
I have tried two things in my routes and both have failed. First, I tried using a namespace route:
namespace :public_activity do
resources :activity do
resources :comments
end
end
This produces the error:
ActionController::RoutingError - uninitialized constant PublicActivity::CommentsController:
Since I do not have a PublicActivity::Activities controller, I tried this instead:
get '/public_activity/activity/:activity_id/comments/new', to: 'comments#new'
post '/public_activity/activity/:activity_id/comments', to: 'comments#create'
However, this does not seem to produce any url helpers at all, as it gives me the following error:
NoMethodError - undefined method `public_activity_activity_comments_path' for #<#<Class:0x007f868e1b7760>:0x007f868e1afd58>:
The reason why I want a route like that is because in my comments view, the commentable can be any model, so I prefer to have a polymorphic form:
<%= form_for [commentable, Comment.new] do |f| %>
...
Am I out of luck? Will I have to hardcore the url for form_for?
IMHO, you only need to play with your polymorphic association and form, Public_Activity will record the activities if you correctly configure that any model of yours.

Resource not generating helper method for create

I have a model called package, which has a controller package created under a name space admin.
so my resource in my routes is declared as below
namespace :admin do
resources :package
end
when I run rake routes
admin_package_index GET /admin/package(.:format) admin/package#index
POST /admin/package(.:format) admin/package#create
new_admin_package GET /admin/package/new(.:format) admin/package#new
edit_admin_package GET /admin/package/:id/edit(.:format) admin/package#edit
admin_package GET /admin/package/:id(.:format) admin/package#show
PUT /admin/package/:id(.:format) admin/package#update
DELETE /admin/package/:id(.:format) admin/package#destroy
If you see there is no helper method generated for create, which should have been admin_packages_path
controller
#newpackage = Package.new
view.html.erb
form_for [:admin,#newpackage] do |f|
end
is reporting that it is not able to find the admin_packages_path. Can somebody please explain how should we declare this in routes to generate the proper helper method for create ?
Your routes are named incorrectly, you're pairing a plural (resources) with a singular (:package).
If you will be working with multiple packages, you should declare resources :packages - this will generate you correctly named routes for all seven RESTful actions (index, show, new, create, edit, update, destroy).
If you are only working with a single package, you will need to specify the URL as an option for your form manually, eg.
form_for [:admin, #newpackage], url: admin_package_path do |f|
You really need to changes the routes to following:
namespace :admin do
resources :packages
end

path defined in routes file is not found

ORIGINAL POST:
I'm probably defining my route incorrectly but I'm following along with this example.
I've defined my routes like this:
namespace :admin do
namespace :distributions do
resources :workflows do
collection do
post :edit_multiple
put :update_multiple
end
end
end
end
obviously there are a bunch of other things within in the admin namespace and I wanted my distributions to belong to the admin namespace and workflows inside of that.
however when I do this:
<%= form_tag admin_edit_multiple_distributions_workflows_path do %>
or this:
<%= form_tag admin_distributions_edit_multiple_workflows_path do %>
I get an undefined method or variable error:
undefined local variable or method `admin_distributions_edit_multiple_workflows_path' for #<#<Class:0x12c2b2320>:0x12c29dfd8>
what'd I do wrong?
You have to put edit_multiple or update_multiple in front, like so:
edit_multiple_admin_distributions_workflows_path
update_multiple_admin_distributions_workflows_path
But, as Nick already mentioned in his comment, rake routes should give you the answer anyway.

Making a controller exist on as a sub-controller, how to fix form routes in rails

I have a ChaptersController that does not have a direct route (i.e. site/chapters/:id) but only exists as a sub route for a BooksController (i.e. site/books/:id/chapters/:id). however, when I try to go to books/:id/chapters/new , I get the following routing error:
Showing .../app/views/chapters/_form.html.erb where line #1 raised:
No route matches {:controller=>"chapters"}
how can I fix this?
It seems like you are using nested routes in this manner:
resources :books do
resources :chapters
end
in which case you should have the named routes 'book_chapter' and 'book_chapters'. You can check this by running rake routes.
In your _form.html.erb partial you need to change this line:
<%= form_for(#chapter) do |f|%>
You need to specify the target URL of the form explicitly, and probably also handle different URLs for create and update scenarios. Try something like this:
<%= form_for(#chapter, :url => (#chapter.new_record? ? book_chapters_path(#book) : book_chapter_path(#book, #chapter) )) do |f| %>
I suppose there is wrong path in /app/views/chapters/_form.html.erb
Check what url is in tag. I suppose you forgot to change it to nested in books.
You may as well paste _form.html.erb here, so i will point it out :)

Resources