Pass multiple parameters by link_to in rails - ruby-on-rails

How can I pass multiple parameters from the view to the controller? I need to perform a request like for example:
GET "/indicators/data?country_id=5&statistic_id=12&anotherparameter_id=anothervalue, ...."
Each parameter is generated by its own link_to selection and I would like to use the parameters together to query my model.
#app/views/indicators/index.html.erb
<!--statistic select button-->
<ul id = "statistics">
<% Statistic.all.each do |stat| %>
<li><%= link_to stat.indicator_name, :action => "data", :controller => "indicators", :statistic_id => stat.indicator_code, remote: true %></li>
<% end %>
</ul>
<!--country select button-->
<ul id = "countries">
<% Country.all.each do |c| %>
<li><%= link_to c.name, :action => "data", :controller => "indicators", :country_id => c.id, remote: true %></li>
<% end %>
</ul>
#config/routes.rb
get 'indicators/data' => 'indicators#data'
#app/controllers/indicators_controller.rb
def data
#country = Country.find(params[:country_id]).name
#statistic = params[:statistic_id]
#queryresult = Mymodel.where(country: #country, statistic: #statistic)
respond_to do |format|
format.js
end
end
EDIT: I had come across answers that advise to do like so:
link_to "Nonsense search", searches_path(:foo => "bar", :baz => "quux")
# => Nonsense search
But in my case I have two different links one with a single parameter corresponding to foo (eg. a checkbox) and the other a single parameter for baz (eg. a dropdown) so to say. The challenge is how to pull the parameters from different links and put them together.

Instead of using controller, action etc you can simply use route_helper_method with params that you want to pass simply.
<li><%= link_to stat.indicator_name, indicators_data_url(countryid: "value", another_id: "value", etc: "etc"), remote: true %></li>
Read about link_to here

Related

ActiveAdmin -- How to access instance variables from partials?

I can't seem to access instance objects in partials. Example:
In controller I have:
ActiveAdmin.register Store do
sidebar "Aliases", :only => :edit do
#aliases = Alias.where("store_id = ?", params[:id])
render :partial => "store_aliases"
end
end
Then in the _store_aliases.html.erb partial I have:
<% #aliases.each do |alias| %>
<li><%= alias.name %></li>
<% end %>
This doesn't work. The only thing that does work (which is horrible to do as I'm putting logic in a view is this:
<% #aliases = Alias.where("store_id = ?", params[:id]) %>
<% #aliases.each do |alias| %>
<li><%= alias.name %></li>
<% end %>
When rendering a partial you need to actively define the variables that are given to that partial. Change your line
render :partial => "store_aliases"
to
render :partial => "store_aliases", :locals => {:aliases => #aliases }
Inside your partial the variables is then accessible as a local variable (not an instance variable!). You need to adjust your logic inside the partial by removing the #.
<% aliases.each do |alias| %>
<li><%= alias.name %></li>
<% end %>
For further reading have a look at the API documentation (specifically the section "3.3.4 Passing Local Variables").
You have to pass your instance variable to your partial in order to use it there:
ActiveAdmin.register Store do
sidebar "Aliases", :only => :edit do
#aliases = Alias.where("store_id = ?", params[:id])
render :partial => "store_aliases", :locals => { :aliases => #aliases }
end
end
Then in your partial you will be able to use it as local variable
<% aliases.each do |alias| %>
<li><%= alias.name %></li>
<% end %>

AJAX Form Issues with Ruby on Rails

I'm sure this question has been asked before in a different context but I'm still so stuck with figuring out AJAX Rails and, I guess, Rails in general (kinda makes me wonder if I should just go back to PHP...). Well anyways I have this form that I want to AJAXify.
This is the "list" view which is part of the "subject" controller
<h1>Listing Subjects</h1>
<ul id="subject_list">
<% #subjects.each do |c| %>
<li><%= link_to c.name, :action => 'show', :id => c.id %></li>
<% end %>
</ul>
<p id="add_link"><%= link_to_function("Add a Subject",
"Element.remove('add_link'); Element.show('add_subject')")%></p>
<div id="add_subject" style="display:none;">
<%= form_tag(:action => 'create') do%>
Name: <%= text_field "subject", "name" %>
<%= submit_tag 'Add' %>
<% end %>
</div>
Code for my "subject" controller
class SubjectController < ApplicationController
def list
#subjects = User.find(:all)
end
def show
#subject = User.find(params[:id])
end
def create
#subject = User.new(params[:subject])
if #subject.save
render :partial => 'subject', :object => #subject
end
end
end
My "subject" partial
<li id="subject_<%= subject.id %>">
<%= link_to subject.name, :action => 'show', :id => subject.id %>
</li>
And the User is just a simple model I made that contains two columns "name" and "email".
How this code currently works is that when you click "Add", the textfield input is revealed. When you type something in the input and submit it, the "_show" partial is rendered in the create link. I was following a Rails 2.0 tutorial but I have 3.0 and I've read through some tutorials and they all mention ":remote => true" and jquery_ujs.js but I have no idea how to apply them to a "form_tag" rather than "form_for" Rails helper.
Basically I want to asynchronously add the element to the bottom of the list without a page load. I've really tried to understand absolutely all of the tutorials I could find but I just can't figure it out.
I believe that you'd better use some Unobtrusive JavaScript to tell to your app
and browser what exactly you want to render and how.
You want too much from simple render :partial => 'subject', :object => #subject line of code.
Here's my snippet that may be helpful to you.
# in the view (:remote => true for form_tag is not problem at all)
<%= form_tag({:controller => :products, :action => :empty_cart }, {:id => 'empty_cart', :remote => true}) do %>
<%= submit_tag 'Clear' %>
<% end %>
# in the controller (note that format.js section in the respond_to block)
def empty_cart
...
respond_to do |format|
format.html { redirect_to :root, :notice => 'Your cart is empty now' } # in the case of disabled JS support
format.js { render :js => "$('#empty_cart').fadeOut()" } # or you can place js code in the empty_cart.js.erb file and specify format.js here without the block
end
end
Check this article if I'm not clear enough.

Rails way to make a horizontal menu

I want to ask you about best rails way to create a menu.
I should to make a horizontal menu. Every page belongs to the specific item of this menu and this item should has id="current" when user opens on this page.
<ul>
<li id="current">Home</li>
<li>About us</li>
</ul>
As I understand I should to create a special helper which will create this html markup and use this helper with special parameter on every view of every page. Maybe there is a better rails way to do this?
PS. Update
My solution:
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :open_most_important
protected
def open_most_important
#menu = {
:cases => { :name => 'Cases', :link => '/cases'},
:groups => { :name => 'Groups', :link => '/groups' },
:projects => { :name => 'Projects', :link => '/projects' },
:settings => { :name => 'Settings', :link => '/settings' },
:about => { :name => 'About us', :link => '/about' }}
#current_menu_item = :cases
end
The fragment of the layout application.html.erb:
<div id="menu">
<ul>
<% #menu.each do |item, value| -%>
<% if #current_menu_item == item -%>
<li id="current"><%= value[:name] %></li>
<% else -%>
<li><%= value[:name] %></li>
<% end -%>
<% end -%>
</ul>
</div>
After I need to set #current_menu_item for every controller in the before_filter
If I understand correctly you want this menu to appear on every page. If that is the case you can just add it to your layout. If you don't understand layouts read up on them at Ruby on Rails Guides http://guides.rubyonrails.org/getting_started.html#customizing-the-layout
This is how I tend to do it:
<%= menu_item("Home", root_path) {
controller.controller_name == "pages" &&
controller.action_name = "home" } %>
<%= menu_item("About us", page_path("about") {
controller.controller_name == "pages" &&
controller.action_name == "about" } %>
The helper:
def menu_item(name, url, options = {})
if yield
options["id"] = "current"
end
link_to name, url, options
end
The "id" will be "current" if the block passed to menu_item returns true.
The way I handle it is to put this in a navigation partial:
<%= nav_link "All Users", users_path, active_tabs.include?('all_users') %>
<%= nav_link "Add User", new_user_path, active_tabs.include?('add_user') %>
And then this helper at the top of each view:
<%= nav 'nav_partials/users_tabs', 'all_users' %> # one view
<%= nav 'nav_partials/users_tabs', 'add_user' %> # another view
And the helpers:
def nav_link(title, path, active, options = {})
if active
options[:class] ? options[:class] += " active" : options[:class] = "active"
end
link_to(title, path, options)
end
def nav(partial, *active_tabs)
partial = "#{params[:controller]}/nav_partials/#{partial}" unless partial.chars.first == '/'
render :partial => partial, :locals => { :active_tabs => active_tabs }
end
To me, it is elegant, even though there are some things that could be a bit better (like the file path thing in the nav helper, as well as referencing params in the helper). But it works very nicely, and it's very flexible.

Does this rails code belong in Application Controller?

I have some code (that is working), but I just want to make sure I am putting it in the right place per rails conventions/best practices. The purpose of the code, is to generate a set of subheading navigation links if '#facility' is defined (which could be done in one of several controllers). Right now, I have the following bits of code spread out as identified below.
My issue: this doesn't feel right, particularly the bit of logic at the beginning of the html template. I will also want to define a few other similar helpers to define these subhead links based on different models. Should this logic (of setting #subhead_links) be in the application controller? As a method in each model (so I would set #subhead_links = #facility.subhead_links)?
I've looked some for answers, but this type of philosophical question isn't as readily google-able as an error code.
in application helper
# build subhead
def subhead_links(facility)
links = [
{ :label => "Configure Facility", :path => facility_path(facility) },
{ :label => "Waitlists", :path => waitlist_tiers_path(:id => facility.id) },
{ :label => "Applications", :path => sponsors_path(:id => facility.id) }
return links
end
in a partial included in application.html.erb template
<% if #facility %>
<% #subhead_links = subhead_links(#facility) %>
<% end %>
<% if #subhead_links %>
<nav class="subnav">
<ul>
<% #subhead_links.each do |link| %>
<li><%= link_to link[:label], link[:path] %></li>
<% end %>
</ul>
</nav>
<% end %>
in various other controllers...
#facility = Facility.find(params[:id])
I never rely on instance variables in partials and try to put as much logic as possible in helpers.
Here this would result in the following:
application_layout:
<%= render_subhead_links(#facility) %>
application_helper:
def render_subhead_links(facility)
if facility
links = [
{ :label => "Configure Facility", :path => facility_path(facility) },
{ :label => "Waitlists", :path => waitlist_tiers_path(:id => facility.id) },
{ :label => "Applications", :path => sponsors_path(:id => facility.id) }
render :partial_name, :links => links
end
end
partial:
<nav class="subnav">
<ul>
<% links.each do |link| %>
<li><%= link_to link[:label], link[:path] %></li>
<% end %>
</ul>
</nav>

Rails: Elegant way to handle navigation?

Right now I have a navigation partial that looks like this (x10 buttons)...
<% if current_controller == "territories" %>
<li><%= link_to "Territories", {:controller => 'territories'}, :class => 'active' %></li>
<% else %>
<li><%= link_to "Territories", {:controller => 'territories'} %></li>
<% end %>
<% if current_controller == "contacts" %>
<li><%= link_to "Contacts", {:controller => 'Contacts'}, :class => 'active' %></li>
<% else %>
<li><%= link_to "Contacts", {:controller => 'Contacts'} %></li>
<% end %>
Is there a more elegant/DRY solution for doing this?
In a similar vein to what Chuck said:
<% TARGETS.each do |target| %>
<li>
<%= link_to target.humanize,
{ :controller => target },
class => ('active' if current_controller == target)) %>
</li>
<% end %>
It's pretty easy to see where the repetition is in there. It's all of the general form:
<% if current_controller == XXXXX %>
<li><%= link_to XXXXX, {:controller => XXXXX}, CLASS %></li>
<% else %>
[do the same stuff minus ":class => 'active'"]
<% end %>
So we want XXXXX and CLASS to be variables (since those are the only things that change) and the rest can be a simple template.
So, we could do something like this:
%w(Contacts Territories).each |place|
<% class_hash = current_controller == place ? {:class => 'active'} : {}
<li><%= link_to place, {:controller => place}, class_hash)</li>
Check out rails-widgets on github. It provides a ton of convenience helpers for rails UI stuff (tabnavs, tooltips, tableizers, show hide toggle, simple css progressbar) in addition to navigation.
Here are the docs
Check out link_to_unless_current. Not exactly what you asked for, but it's close.
Also, you could put this kind of logic in a helper to abstract it out of the view.
Check out the simple-navigation plugin. It's an 'easy to use' rails plugin for creating navigations for your rails apps.
A slightly different version w/ link_to_unless_current:
<ul>
<% links.each do |link| -%>
<li><%= link_to_unless_current link.humanize, { :controller => target } %></li>
<% end -%>
</ul>
A good resource for stuff like this are the rails docs.

Resources