How to create a new_X_path url dinamically in template - ruby-on-rails

I have a link in my partial template:
link_to 'Add', new_photo_path
But I want to make this partial template shared. Is there any way to make 'new_CONTROLLER_path' url automatically? The CONTROLLER must be replaced by current controller.

Try this:
link_to 'Add', [:new, params[:controller].singularize]
Internally, Rails will convert [:new, params[:controller].singularize] to a call to new_controller_name_path(e.g. if controller posts then [:new, params[:controller].singularize] generate a path helper like new_post_path).
Most (if not all) Rails methods that expect a path will also take an object representation of your resource, like respond_with, link_to, render, redirect_to, form_for, etc.

Try something like this:
link_to 'Add', eval("new_#{params[:contoller].singularize}_path")
params[:contoller].singularize will return you photo or any controller name related to request eval will do rest.

Related

Calling a specific action in a form tag

I have an action vote_for in my question controller.
what is the helper that enbales me to call this action from a view?
i tried :
vote_for_question_path(#question)
but this didn't work. ?
Since you've already defined resourceful routes for the Question resource, you should start by adding a member route on your existing resource route:
# config/routes.rb
resources :questions do
member do
get 'vote_for'
end
end
This will create the following route:
vote_for_question GET /questions/:id/vote_for(.:format) questions#vote_for
Next, create a controller action for the resulting route:
# app/controllers/questions_controller.rb
def vote_for
# logic goes here
end
Finally, in your view, you can construct a link to the route by passing the collection path to the link_to helper:
<%= link_to "Vote", vote_for_question_path(#question) %>
UPDATE:
If you'd rather represent the link as an HTML button than an <a> tag (as the OP is proposing in the comments to this answer), you can use the button_to form helper as follows:
<%= button_to "Vote", vote_for_question_path(#question), method: "get" %>
Note that, because you're replacing the link with a button, you should ensure that you're passing the correct HTTP submission method (which is GET in this instance) as an argument.
The path helpers only come when you define them in your routes.rb as a named route. So if you want a named non-RESTful route (which you do), you should add to your routes file:
get 'vote_for_question/:id', to: 'question#vote_for', as: 'vote_for_question'
And then you can call vote_for_question_path(#question.id) in your views and it will generate e.g. /vote_for_question/1.
See http://guides.rubyonrails.org/routing.html#generating-paths-and-urls-from-code for more on this.

link_to custom action but wrong method?

all, I'm trying to get a custom action to work with a put method: in the
in _post.html.erb i have a link_to statement:
<%= link_to 'End now', post, :method => :put, :action => endnow %>
routes.rb contains:
resources :posts do
member do
put :endnow
end
and posts_controller.rb looks like:
class PostsController < ApplicationController
helper_method :endnow
[.. code for create, edit, destroy, etc ..]
def endnow
puts params
end
end
rake routes's relevant line looks like:
endnow_post PUT /posts/:id/endnow(.:format) posts#endnow
However, the action endnow helper doesn't run when clicking on this link.
Strangely, it does run with an index action (which i can tell from the puts command.
Of course, eventually the code for endnow will update #post, but for now, it just doesn't run properly.
Maybe i'm going about this the wrong way - all I'm trying to achieve is to update #post upon clicking the link to that post, and before showing it.
Any ideas / Alternatives?
Why not use the route helper method provided to you? Change your link to
<%= link_to 'End now', endnow_post_path(#post), method: :put %>
Things you're doing wrong:
If you want to specify the :action, use the Symbol for the action (you're missing a colon). :action => endnow should be action: :endnow
I will assume you have a #post instance variable you're passing from your controller to your action. You should be using that instead of post (unless you do in fact have a local post variable you're omitting from your code)
You are using endnow as an action; you should remove the helper_method :endnow line in your controller because it's not something you want to/should be accessing from your view.
This can all be avoided by using the route helper (for endnow_post you'd append _path to get the local route path: endnow_post_path), and pass in your #post as an argument.
Because you're trying to do a PUT request, you must make sure you have something like jquery-ujs included in your asset pipeline to convert these links to form submissions behind the scenes; browsers don't support PUT via the click of a link on their own.
As for why you're getting the template error when you get your link_to working, Rails is telling you that you need to create a app/views/posts/endnow.html.erb file. Your action has only puts params which does not terminate execution, leaving Rails to assume you still are trying to render some endnow.html.erb template.
Are there other ways to do what you're trying to do (change a single attribute of a specific model)? Sure. Are there better ways? That's pretty subjective; it may not be the most RESTful way, but it's arguably easier to deal with (if for example there are very specific authorization rules to check before updating the attribute you are modifying in endnow. Does the way you've started fleshing out work? Absolutely.
Finally, as a bump in the right direction, after you fix your link_to and remove the the helper_method as I have described above, your endnow action might look like this:
def endnow
post = Post.find!(params[:id])
post.some_attribute_here = some_new_value_here
post.save
redirect_to :root and return # <- this line sets a redirect back to your homepage and terminates execution, telling rails to do the redirect and **not** to render some endnow.html.erb file
end

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)

simple link_to in rails

I have a page app/views/new/news.html.erb and I simply want to link to this page from within my layouts/application.html.erb. Can someone please help! I have been struggling with this all morning.
I have tried things like <%= link_to "News", ... But I'm not really sure where to go from there.
You don't "link" to a view, you link to a controller which renders that view. Then, you'll need an entry in your routes.rb to wire up the url routing for that controller. If you have a controller named NewsController with a method called index and an entry in your routes.rb that looks like resources :news the following link_to should work: link_to "News", news_path.
In case it's not clear, the index method in your NewsController needs to have render :news in it.
Sounds like you may want to check out the guide on this topic: http://guides.rubyonrails.org/routing.html
If you have it setup correctly you should have a plural for your controller (i.e. news instead of new) and the following should work:
<%= link_to 'News', :controller => "news", :action => :news %>
This is assuming you are using scaffold.
If are adding this folder and page manually: for dynamic page, you have to create an action in your controller. For static page, you have to put it in your public folder.
You can always run
rake routes > routes.txt
in your application directory, which will dump a list of all routes into a txt file. Choose path that leads to action and controller you want, and then supply it as a param for link_to method :)

Generate a `link_to` to the controller action `edit`, dynamically

I am using Ruby on Rails 3.0.7 and I would like to generate a link_to to the controller action edit, dynamically. I have to use it in a partial template but the issue is that I am rendering that same partial template for different model data (that is, I pass local variables of different class instances in that).
So I can not use the route "magical RoR way"
`edit_<singular_name_of_the_resource>_path(<resource_class_instance>)`.
I would like to make something like the following:
link_to( #resource_class_instance, :action => 'edit') # This example is wrong, but it suggests the idea
Is it possible? If so, how can I do that?
You can write routes using the "array style" like this :
= link_to "Edit", [:edit, #your_resource]
There is a edit_polymorphic_url and (edit_polymorphic_path) helper available:
https://github.com/rails/.../polymorphic_routes.rb#L32

Resources