Path helpers in a loop - ruby-on-rails

I have a Foo that :has_many Bars. GET Foo#index shows all of the Bars. View looks like this:
<% #foos.each do |foo| %>
<% foo.bars.each do |bar| %>
<%= link_to 'Download', download_bar_path %>
<%= link_to 'New', new_bar_path( :foo => foo.id ) %>
<% end %>
<% end %>
There is a def download in Bars controller and a route:
resources :bars do
member do
get 'download'
end
end
rake routes shows
download_bar GET /bars/:id/download(.:format) {:action=>"download", :controller=>"bars"}
and URL /bars/1/download really works, but the first link in the view (download_bar_path) doesn't. It says No route matches {:action=>"download", :controller=>"bars"}.
What can be the problem?

<% #foos.each do |foo| %>
<% foo.bars.each do |bar| %>
<%= link_to 'Download', [:download, bar] %>
<%= link_to 'New', [:new, :bar] %>
<% end %>
<% end %>

You didn't specified the bar to download, you need to add it by changing this line
<%= link_to 'Download', download_bar_path(bar) %>

Related

How do I create this link_to conditional in a DRY way?

I want to do the following:
<% if current_user.has_role? :demo %>
<%= link_to profile_path(#selected_profile) do %>
<% else %>
<%= link_to profile_path(profile) do %>
<% end %>
What's throwing it off is the beginning of the block in the link_to, within the if statement.
So how do I achieve this without having to duplicate ALL of the code within this if block twice?
Edit 1
This is the error I get from the above code:
SyntaxError at /
syntax error, unexpected keyword_else, expecting keyword_end
'.freeze; else
^
You can do it like this:
<% chosen_profile = current_user.has_role?(:demo) ? #selected_profile : profile %>
<%= link_to profile_path(chosen_profile) %>
So this will not repeat your link_to tag which you need to do. As you have to redirect to the same path and just change the profile object then this will work. You may change the ternary to if else block if the line seems very long and not readable.
And as everyone mentioned that don't use a do after link_to until you need a block. So that will fix your error.
You can achieve this by defining method in you user.rb (Model)
def demo?
self.has_role?("demo")
end
Then you write in your view
<% if current_user.demo? %>
<%= link_to profile_path(#selected_profile) %>
<% else %>
<%= link_to profile_path(profile) %>
<% end %>
This may help you.
do should have end.
Here is the Ruby Doc reference for link_to
Here is more about do in Ruby
<% if current_user.has_role? :demo %>
<%= link_to profile_path(#selected_profile) do %>
selected profile
<% end %>
<% else %>
<%= link_to profile_path(profile) do %>
profile
<% end %>
<% end %>
You are getting error because of do, you are opening the block but not closing it, try this code
<% if current_user.has_role? :demo %>
<%= link_to 'Profile', profile_path(#selected_profile) %>
<% else %>
<%= link_to 'Profile', profile_path(profile) %>
<% end %>
or, you can do it in controller instead
#selected_profile = current_user.has_role?(:demo) ? #selected_profile : profile
and then in the view,
<%= link_to 'Profile', profile_path(#selected_profile) %>
Hope that helps!

Rails: Displaying pages navigation inside application layout

I'm trying to display a page navigation but Rails in addiction to page_title outputs all the record's informations inside brackets like this:
- About [#<Page id: 1, page_title: "About", page_content: "About page content", created_at: "2013-05-04 06:38:03", updated_at: "2013-05-04 06:38:03">]
- Other page [#....etc...]
How I can fix this? Thx.
application.html.erb
<li>
<%= #pages.each do |p| %>
<%= link_to page_path(p.id) do %>
<%= p.page_title %>
<% end %>
<% end %>
</li>
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :set_layout_variables
def set_layout_variables
#pages = Page.all
end
end
remove the = in your line <%= #pages.each do |p| %>
It should be
<li>
<% #pages.each do |p| %>
<%= link_to page_path(p.id) do %>
<%= p.page_title %>
<% end %>
<% end %>
</li>
<%= will output the result of the line (in your case, the loop), which displays the page record. That's why you see the record in your output.

cannot display the view from the url parameter in ruby

I was trying to display a list of the blog with the same category which display on the url parameter. however when i click the link it still stay at the same page.
route
match '/microposts/:category', :to => 'microposts#category_list'
view
<h2>sidebar</h2>
<% #categories= Micropost.select("category").group("category")%>
<% unless #categories.nil? %>
<ul><% #categories.each do |category| %>
<li><%= link_to category.category, :controller =>"microposts", :category => category.category, :method => 'category_list' %></li>
<% end %>
</ul>
<% end %>
After click the link enter category_list view.
category_list.html.erb
<h2>Catergory</h2>
<% #microposts.each do |post|%>
<article>
<h4><%= link_to post.title, post %>| <%= post.created_at %></h4>
</article>
<% end %>
<%= will_paginate #microposts %>
microposts controller
def category_list
#micropost = Micropost.select("category").where(params[:category])
#title = "Category"
end
Ok, try this:
UPDATED:
microposts_controller.rb
def category_list
#microposts = Micropost.where('category = ?', params[:category])
#categories = Micropost.select('DISTINCT(category)').map(&:category).compact
...
end
routes.rb
match '/microposts/:category' => 'microposts#category_list', :as => :microposts_category_list
_sidebar.html.erb
<h2>sidebar</h2>
<% unless #categories.empty? %>
<ul>
<% #categories.each do |category| %>
<li><%= link_to category, microposts_category_list_path(category) %></li>
<% end %>
</ul>
<% end %>

CASE WHEN Menu based off of Routes.rb and Request.path

I have a case when clause where based on the URL that you're at, it will bring in different menu options. However, depending on some of the menus that you could be at, it doesn't recognize that you have some variables assigned. The system errors:
ActionController::RoutingError in Pages#users_page
Showing /home/initiald/RubymineProjects/SOWOnline/app/views/layouts/_navigation.html.erb where line #27 raised:
No route matches {:controller=>"results", :action=>"show"}
Here is the code that I have so far
<% case request.path %>
<% #ROOT AND SETTINGS %>
<% when '/', settings_path, '/guest' %>
<% #SURVEY AND RESULTS %>
<% when '/sow_survey', '/surveys', '/results', result_path, results_path, available_surveys_path, take_survey_path, view_my_survey_path, edit_my_survey_path %>
<% if permitted_to? [:admin, :partner, :employee], :users %>
<%= link_to 'new survey', available_surveys_path %>
<%= link_to 'edit survey', results_path %>
<% end %>
<% #USERS %>
<% when '/register' , '/users', '/sow_users', edit_user_path %>
<% if permitted_to? [:admin, :partner, :employee], :users %>
<%= link_to 'new user', register_path %>
<%= link_to 'list users', list_users_path %>
<% end %>
<% else %>
<% end %>
There is no any result_path without attributes, but there is result_path(result_id) path, which is:
{:controller=>"results", :action=>"show", :id => your_paticular_id}
and looks like
/results/:id
UPD
Just use regular expression here:
<% when '/sow_survey', '/surveys', '/results', /\/results\/\d*/, results_path, available_surveys_path, take_survey_path, view_my_survey_path, edit_my_survey_path %>
And yes - your code is messy.

Ruby/Rails Conditional search method (if ... else "no results found")

Here is the code of a "simple search form" (thanks to jordinl) which I try to improve. I would like to add the case if there is no match found.
So, there is the view (views/users/index.html.erb)
<% form_tag users_path, :method => 'get' do %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
<% end %>
<% #users.each do |user| %>
<p><%= link_to "#{user.name}", user %></p>
.
.
.
<% end %>
The controller ( users_controller.rb)
def index
#users = User.search(params[:search])
end
and the method in user model:
def self.search(search)
search.blank? ? [] : all(:conditions => ['name LIKE ?', "%#{search.strip}%"])
end
I tried the following:
def self.search(search)
if search.to_s.size < 1
[]
else
if #users.size > 0
all(:conditions => ['name LIKE ?', "%#{search.strip}%"])
else
render :text => "No result found"
end
end
end
reporting the following error: "You have a nil object when you didn't expect it!..." (no instance in the array). Then, I tried to add
<% if #users? %>
<% #users.each do |user| %>
.
.
.
In the view. But it doesn't work either.
I would be pleased to understand why I'm wrong on this. Thank you!
You're on the right track. Try this:
<% if (#users) %>
<% if (#users.empty?) %>
<p>No users found.</p>
<% else %>
<% #users.each do |user| %>
<p><%= link_to "#{user.name}", user %></p>
<% end %>
<% end %>
<% else %>
<p>Use the search form to search for stuff.</p>
<% end %>
Change your search method to only return something if searching was used:
def self.search(search)
search.present? and all(:conditions => [ 'name LIKE ?', "%#{search.strip}%" ])
end
you can't render in your model.
In your view:
<% form_tag users_path, :method => 'get' do %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
<% end %>
<% if #users.empty? %>
No records found!
<% else %>
<% #users.each do |user| %>
<p><%= link_to "#{user.name}", user %></p>
<% end %>
<% end %>
In your model:
def self.search(search)
search.blank? ? [] : all(:conditions => ['name LIKE ?', "%#{search.strip}%"])
end
You are close with your check on #users? but it should be:
<% if !#users.empty? %>
<% #users.each do |user| %>
...
<% end %>
<% else %>
No users found.
<% end %>
This will work with your original self.search implementation which, correctly, is used just to find users and does not need to worry about reporting if none are found.
Your self.search method should return an array, either full or empty. Try:
in you model
def self.search
self.all(:conditions => ['name LIKE ?', "%#{search.strip}%"])
end
and in your view
<% if #users? %>
<% #users.each do |user| %>
…
<% end %>
<% else %>
No result
<% end %>

Resources