Rails: link_to only if route exists - ruby-on-rails

I'm writing a Rails Engine and in one of my views I'd like to create a link to main_app if a named route exists.
I will give an example to clarify the question:
The Main application may or may not define in routes.rb:
resources :my_resource, only: :index
In my rails engine I need to add a link to my_resource_path only if main_app defined that route. I think it should be something like the following:
<%= link_to "Link", main_app.my_path if my_resource_path_exists? %>
I tried:
<%= link_to "Link", main_app.my_resource_path if
main_app.respond_to?(:my_resource_path) %>
but, when the path does not exist, that raises NoMethodError:
undefined method `my_resource_path' for #<Module>
How my_resource_path_exists? method could be implemented? I'm using ruby 2.2 and rails 4.2
The question is related to: Determine if path exists as route in Rails controller
But in this case, I have a named route (my_resource_path), so I need something slightly different, but can't figure out by myself.

I found a solution wich does not require to recover from fail. It's possible to check if the route is defined using url_helpers:
Rails.application.routes.url_helpers.method_defined?(:my_path)
So, the code could be written like that:
<%= link_to "Link", main_app.my_resource_path if
Rails.application.routes.url_helpers.method_defined?(:my_resource_path) %>

You could either use main_app.try(:my_path) or rescue NoMethodError to return false.

Related

Undefined method in controller (Routing)

I'm new at rails and I'm currently working on an already existing application that handles butons like so:
<%= link_to 'Edit', edit_answer_path(ans) %>
That links to the file /answers/edit.html.erb but now I need to make a button that links to the file /answers/comment.html.erb how do I go about doing this?
I already tried with
<%= link_to 'Comment', comment_answer_path(ans) %>
but I get the error "Undefined method 'comment_answer_path'" even after adding this lines to answers_controller :
def comment
ans = Answer.find(params[:id])
end
You need to add a route to your config/routes.rb and then restart the server. Something like
resources :answers do
member do
get 'comment'
end
end
will create the comment_answer_path helper for you as well.
It depends on how you've set up the routes in routes.rb.
You can use rake routes to see the list of all paths and their alias.

How do you create a link to a .html.erb file in Ruby on Rails?

Ive created a new about page in Ruby on Rails called about.html.erb. How do I create a link to it?
Here is another link I have, Im just not how to write another one for myself.
<%= link_to "Learn more", new_property_path, class: "btn btn-home" %>
check out documentation for #link_to. If you are not sure about second argument you can run bundle exec rake routes and check what url helper you need to use.
You'd probably need to create a route in config/routes.rb for this new "about" action.
An example of route would be:
get "about" => "<name_of_controller>#about", as: "about"
PD: Remember to change the to the actual controller's name.
Then you will be able to use a link like this:
<%= link_to "About", about_path, class: "btn btn-home" %>
<%= link_to "Learn more", new_property_path, class: "btn btn-home" %>
So it's quite straight forward - the first is the name, the last is the css class, you can and probably should reuse these to maintain visual consistency. The middle bit is the piece that will confuse you.
the path comes from your routes.rb file - which is in the config directory. You will need to have a path set up there to use it in the link.
You can run 'rake routes' to see the current mappings that you have. you get a format of:
new_user_account GET /user/new(.:format) user#new
They key to them is that you add path to the first item - so 'new_user_account_path' and it will point to 'user#new' which is the new method in the user controller.
To add routes, you edit the file, and while there are quite a few ways of doing things, your basic CRUD operations are covered by a line of:
resources :users
This will give you more info:
http://guides.rubyonrails.org/routing.html is a guide to this

Cant create a link to named routes

I want to create a link to a named route
My routes.db have the following rule
match '/tablero', to: 'tablero#index',via: 'get' , as: 'tablero_main'
I can see the route using rake routes
tablero_main GET /tablero(.:format) tablero#index
But when i use the link_to as follows i get the "undefined local variable or method `tablero_main'" error.
<%= link_to "Tablero",tablero_main %>
Is there anything else i am missing?
You need to append path to the method name, like so:
<%= link_to "Tablero", tablero_main_path %>
Routes
To help you further, you'll need to also consider the role of resources in your routes
As Rails uses a resourceful routing infrastructure, every route you create should be based around a resource. In your case:
#config/routes.rb
resources :tablero, only: :index #-> domain.com/tablero
Admittedly, this will give you the path tablero_index_path, rather than tablero_main_path, but it ensures your routes are not only DRY, but also extensible. Nothing worse than having 100's of "match routes in a route file.
--
Helpers
After that, remember to use the correct route_path helper:
Each "route" path is basically just a helper method (which builds a URL for you). When using link_to, you need to reference the path helper directly. You didn't do this, which lead Rails to come back with the undefined method error

Is there a way to get Rails to guess a resource's #edit path the same way it does with the #show path?

In Rails, you can do link_to "text", resource or url_for resource and Rails will try to guess the path to the resource from the resource's class and id. Is there any way to do the same by for the edit link?
I could probably have something together to just append "/edit" the the #show path, but that doesn't seem very pleasant.
Side question: is there a way to get the collection path for a model given the model class?
link_to 'Edit This Thing', [:edit, #thing] # = edit_thing_path(#thing)
link_to 'Things Index', Thing # = things_path
These call polymorphic_path under the hood, as you already mentioned.
I found polymorphic_path, which seems to do the trick. You call it in this fashion:
polymorphic_path([:edit, resource])
I think this is what you're looking for:
link_to "text", edit_resource_path(resource)

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