Can i use variable for Rails link_to helper for making different link with variables?
For example,
<%= link_to users, users_path %>
I have link like this,
And i'd like to change this url with variable examples
So i changed url like this,
<%= link_to users, "#{examples}_path" %>
This not worked because of whole string change to url.
How can i change my link_to for use this with different variable for DRY codes?
What you're asking is really just how to perform dynamic method calls. In Ruby you can do it with send (and public_send):
<%= link_to users, send("#{examples}_path") %>
The difference between the two is that send will let you violate encapsulation and call private/protected methods.
You can also do it by calling call on the Method object:
<%= link_to users, method("#{examples}_path".to_sym).call %>
However you most likely don't even need this it in the first place. Just use the polymorphic routing helpers to create links from models:
# a link to show whatever resource happens to be
<%= link_to resource.name, resource %>
<%= link_to "Edit", edit_polymorphic_url(resource) %>
<%= link_to "New", new_polymorphic_url(resource_class) %>
<%= link_to "Frobnobize", polymorphic_url(resource, :frobnobize) %>
# a link to the index
<%= link_to resource_class.model_name.plural, resource_class %>
These all use a set of heuristics to figure out what the corresponing path helper is and then call it dynamically with send.
Or if you want to link to a specific controller or action just use the functionality provided by url_for:
# link to a specific controller action
<%= link_to "Baz", { controller: :foo, action: :bar } %>
# Will use the current controller
<%= link_to "Baz", { action: :bar } %>
Related
I have two engines in refinerycms: product and order. Im trying to call "create" method of orders while being on the product show page, but cant get the right syntax.
The html is:
<%= form_tag({controller: 'orders', action: 'create'}, method: 'post') do %>
<%= submit_tag('Submit') %>
<% end %>
And the error is :
No route matches {:action=>"create", :controller=>"refinery/products/orders", :id=>"category1", :locale=>:en}
The route I`m looking for is(from rake routes log):
orders_orders POST /orders(.:format) refinery/orders/orders#create
I`ve tried different variants, like:
<%= form_tag(url_for({controller: 'orders', action: 'create'}), method: 'post') do %>
<%= submit_tag('Submit') %>
<% end %>
<%= form_tag({controller: 'refinery/orders/', action: 'create'}, method: 'post') do %>
<%= submit_tag('Submit') %>
<% end %>
And some other. But had no luck.
How can I call 'create' method of orders from products/show page and transfer there correct params?
Well, I have used a kind of workaround to accomplish my goal. Do not know if this is a ruby-way, but still:
1. I have created a new action in my products controller.
def ordering
#Call any method you like.
end
I have added this in routes:
post 'shop/products/ordering' => 'refinery/products/products#ordering'
Still this is not a good solution, because there is no way to call actually another controller`s method without directly creating an instance of this controller or marking the method as a class method, not instance.
In any case, I`d be very grateful if someone could explain in details or show any documentation on how to do such things directly.
UDP: I`ve found a good way in search engine for this cms.
<%= form_tag refinery.search_root_path, method: 'get' do %>
<%= label_tag 'query', t('.search_label') %>
<%= text_field_tag :query, {}, {type: "search", placeholder: t(".search_site_for"), value: (params[:query] if params[:query])} %>
<%= submit_tag t(".go") %>
<% end %>
I want to show button with image.
I have this code
<%= image_submit_tag "down.png", controller: "posts", action: "votedown", post_id: post.id, topic_id: post.topic_id, class: "xta" %>
Its visible properly but not calling action "votedown"
In my routes I have
post '/votedown', to: 'posts#votedown
Please also suggest if there is any other way to call the method votedown with params and image "down.png"
image_submit_tag must be used in conjunction with a form - it works just a normal html <input type="submit"> button.
You might also want to change your route definition into something more restful:
patch '/posts/:id/votedown' => "posts#votedown", as: 'votedown_post'
This makes it more apparent that this route acts on a post - and we use the PATCH method since we are changing a resource instead of creating a new resource.
Armed with our new route we can simply create a form:
<%= form_for(#post, url: votedown_post_path(#post) ) do |f| %>
<%= image_submit_tag "down.png", class: "xta" %>
<% end %>
Note that you do not need to add an input for the post id since it will be available as params[:id].
Another way to do this would be to use Rails unobstructive javascript driver to create a link or button which sends a PATCH request to '/posts/:id/votedown'.
<%= link_to image_tag("down.png", class: "xta"), votedown_post_path(#post), method: :patch %>
It's a little late here so maybe this a trivial question where I'm missing something simple. But when I click a button (with link_to) I created the following gets appended to my URL:
%23<ActionView::Helpers::FormBuilder:0x3ef1fd8>
Why is this, and how can I prevent this? Again, I apologize if this is a shallow question. I can post more information regarding routes and whatnot if that is needed.
Thanks!
Edit: More information as requested.
View:
<%= link_to "Index", welcome_path(f), :class => 'button' %>
with f being part of a form_for loop. I think I'm passing the wrong parameter but I'm unsure.
Relevant Route:
get "index" => 'welcome#show', :as => 'index'
Update:
Thanks for the help everyone. I ended up getting it working by pluralizing my controller (I don't know why I didn't have that before) and utilizing welcome_url instead. That seemed to do the trick.
Check out the very first example and paragraph in the Rails API docs for ActionView::Helpers::FormBuilder:
<%= form_for #person do |f| %>
Name: <%= f.text_field :name %>
Admin: <%= f.check_box :admin %>
<% end %>
What this is saying is that f represents an instantiated FormBuilder object that you are passing to the welcome_path method in your link_to helper.
Typically, you would not mix #index and #show in your routes. Depending on what you want to use the WelcomesController for, you might actually want to route your root_path to welcome_index:
get "welcome/show" => 'welcome#show', :as => 'welcome'
root 'welcome#index'
You should run: $ rake routes in the terminal to get an idea of path view helpers that you can use in your app.
Maybe you're trying to send users to a personalized welcome page. You could have something like this for your corresponding link_to helpers would look best like this:
<%= link_to "Show", welcome_path(#user.id), :class => 'button %>
<%= link_to "Index", root_path, :class => 'button' %>
I have an Article resource and have defined resourceful routes for it. I want to create a simple page that shows the articles of the current user. I am aware that it is possible to do so by adding another action, for example 'search' to articles controller which will contain the custom code that searches for articles that have the same user id. And for the routes:
resources :articles do
get 'search'
end
But I'm not sure if adding a custom action is a good idea in this case. I'm thinking I can still use the index action (which shows all articles) and pass some sort of parameter from the url so that it can distinguish if the user wants to see all articles or just his own. But I'm not sure exactly how this can be done. Any help would be great. Thanks!
You can use the query string to pass parameters. see here
So you can pass something like .../articles?user_id=2
In your controller, just change the behavior according to the user_id parameter.
you don't need to create a new action/view for it.
You can add a small form to filter all articles or only my articles, for example:
<%= form_tag articles_path, method: :get do %>
<%= radio_button_tag :search, "all", :checked => true %>
<%= label_tag :all %><br />
<%= radio_button_tag :search, "my" %>
<%= label_tag :my_articles %><br />
<%= submit_tag "filter", name: nil %>
<% end %>
than in your controller:
def index
if params[:search] == 'my'
#articles = current_user.articles
else
#articles = Article.all
end
On my user model, I have a bunch of attributes like is_foos_admin and is_bars_admin that determine which kinds of records a user is allowed to edit.
I'd like to DRY out my edit links, which currently look like this:
<%= link_to 'Edit', edit_foo_path(foo), :class => 'edit' if current_user.is_foos_admin? %>
...
<%= link_to 'Edit', edit_bar_path(bar), :class => 'edit' if current_user.is_bars_admin? %>
I want to make a helper that lets me pass in a foo or bar and get back a link to edit it, like so:
<%= edit_link_for(foo) %>
The helper might look like this (which doesn't work):
def edit_link_for(thing)
if current_user.is_things_admin?
link_to 'Edit', edit_polymorphic_path(thing), :class => 'edit'
end
end
The model-agnostic edit_polymorphic_path method gets me halfway there, but it's the "is_things_admin" method that I don't know how to universalize. If I could use interpolated Ruby inside of a helper, I'd want to do something like
if current_user.is_#{thing.class.name.downcase.pluralize}_admin?
But of course that doesn't work. Any ideas?
Try using send:
if current_user.send("is_#{#model}_admin?")