The following displays a list of documents grouped by subject and the name of each document is the name of the packet type. How do I display the the count for each packet type name? so for example if there are two documents for the first subject and their packet type names are 'class' how do I display 'class 1 of 2' and class 2 of 2' next to the packet type name?
controller:
class DevelopController < ApplicationController
def index
list
render('list')
end
def list
#subjects = Subject.includes(:documents => :packet_type)
end
end
view:
<ol>
<% #subjects.each do |subject| %>
<li><%= subject.subject_name %>
<ul>
<% subject.documents.each do |document| %>
<li><%= document.packet_type.name %></li>
</li>
<% end %>
</ul>
<% end %>
</ol>
You can get the total count with .size or .count. To get the current index, you can use each_with_index instead of each. And here on a silver plate : http://apidock.com/ruby/Enumerable/each_with_index :)
Related
I'd like to group a collection alphabetically by title:
#projects = Project.find_all_by_user_id(current_user.id)
The view should contain a list of projects grouped by title, e.g.:
A
Andre's Project
Ananas
C
Chemnitz
Cleopatra
F
Find a new office
S
Super secret stuff
But I got no clue how to do this in rails. Does rails provide a functionality to do this or do I need to write my own loop looking for the titles etc.?
Thank you!
Not Rails but Ruby does the trick. In your view:
<% #projects.group_by{ |project| project.name[0].downcase }.each do |letter, projects| %>
<div id="letter-<%= letter %>" class="letter-group">
<h2><%= letter.upcase %><h2>
<% projects.each do |project| %>
<p><%= link_to project.name, project %></p>
<% end %>
</div>
<% end %>
group_by (ruby-doc) returns a hash you can easily loop through with letters as keys and arrays of corresponding projects as values. Be sure to already get your records sorted by project's name: (in your controller)
#projects = Project.order("name ASC").find_all_by_user_id(current_user.id)
I have a list of organisations, grouped and displayed by their name, in alphabetical order. I want to display these across 4 columns for each letter, i.e.:
A
A... A... A... A...
A... A... A... A...
...
Z
Z... Z...
I have used the following code:
<% #organisations.keys.sort.each do |starting_letter| %>
<div class="page-chunk default">
<h6><%= starting_letter %></h6>
<% #organisations[starting_letter].each do |organisations| %>
<% organisations.in_groups_of(4).each do |column| %>
<div class="one_quarter">
<% column.each do |organisation| %>
<%= link_to organisation.name, organisation_path(organisation) %><br />
<% end %>
</div>
<% end %>
<% end %>
</div>
<% end %>
And in the controller:
#organisations = Organisation.all.group_by{ |org| org.name[0] }
But get undefined methodin_groups_of' for #for my troubles. If I change the code to#organisations[starting_letter].in_groups_of(4).each do |organisations|then I get aNilClass` error.
What have I done wrong and how should I fix it?
Try organisations.in_groups_of(4, false)
Without the false, it will fill in any empty spots in the last group with nils, which means it will try to call name on nil.
I have the following code in my Rails 3 application:
Show view (from another model called animal.rb)
<% #animal.labs.each do |lab| %>
<li>
<%= lab.TestDone.strftime("%d %b. %Y") %>
<h5><%= lab.TestType %></h5>
<h6><%= lab.TestLower %></h6>
<b><%= lab.TestResult %></b>
<h6><%= lab.TestUpper %></h6>
</li>
<% end %>
lab model
belongs_to :animal
default_scope :order => "TestDone DESC", :group => "TestDone"
The above code successfully group all results by date. However, it only shows the first of each value after the date.
For example, if the output was originally (before the grouping) like this:
<li>
26 April 2012
<h5>Glucose</h5>
<h6>1.0</h6>
<b>1.8</b>
<h6>2.0</h6>
</li>
<li>
26 April 2012
<h5>WBC</h5>
<h6>1.1</h6>
<b>2.8</b>
<h6>3.0</h6>
</li>
<li>
26 April 2012
<h5>ABC</h5>
<h6>1.0</h6>
<b>1.6</b>
<h6>2.0</h6>
</li>
then it would output the following after the grouping:
<li>
26 April 2012
<h5>Glucose</h5>
<h6>1.0</h6>
<b>1.8</b>
<h6>2.0</h6>
</li>
What is the correct way of producing something like this:
<li>26 April 2012</li>
<li>
<h5>Glucose</h5>
<h6>1.0</h6>
<b>1.8</b>
<h6>2.0</h6>
</li>
<li>
<h5>WBC</h5>
<h6>1.1</h6>
<b>2.8</b>
<h6>3.0</h6>
</li>
<li>
<h5>ABC</h5>
<h6>1.0</h6>
<b>1.6</b>
<h6>2.0</h6>
</li>
So I have a date heading and then every record with that date is listed below?
A simpler way would be to use group_by like so:
<% #animal.labs.group_by{|l| l.TestDone.strftime("%d %b. %Y") }.each do |testdate,labs| %>
<li><%= testdate %></li>
<% labs.each do |lab| %>
<li>
<h5><%= lab.TestType %></h5>
<h6><%= lab.TestLower %></h6>
<b><%= lab.TestResult %></b>
<h6><%= lab.TestUpper %></h6>
</li>
<% end %>
<% end %>
http://api.rubyonrails.org/classes/Enumerable.html#method-i-group_by
Grouping not works the way you want to use it. First, yo ushould not group it in your default_scope, but you may use some aggreagation in the view, or in the controller.
Model:
default_scope :order => "TestDone DESC"
View:
<% prev = nil %>
<% #animal.labs.each do |lab| %>
<%= "</ul></li>" if prev != nil && prev != lab.TestDone %>
<%= "<li>"+lab.TestDone.strftime("%d %b. %Y")+"<ul>" if prev != lab.TestDone %>
<li>
<h5><%= lab.TestType %></h5>
<h6><%= lab.TestLower %></h6>
<b><%= lab.TestResult %></b>
<h6><%= lab.TestUpper %></h6>
</li>
<% prev = lab.TestDone %>
<% end %>
<%= "</ul></li>" if prev != nil %>
Not the most pretty solution, but it is based on your code.
Basically you need to store the last element's date, in order to compare it with the actual element's date. If they differ, then the new date must be shown. Because they ordered by date, the elements with the same date are close to each other.
I think that is what you was looking for.
I need to create some type of helper for a form where it will create a select for each day of the week.
Below, creates the 5 instances, but only submits the last one.
def basic_question(q)
a = ""
5.times do
a << select("question[question_id_#{q.id}]", :response, (0..30).to_a) + " for #{q.survey.publish_on.strftime('%A')} #{q.survey.publish_on.strftime('%D')} <br />"
end
return a.html_safe
end
EDIT
Here is the view to take the survey
<%= form_for store_survey_path(#survey) do |f| %>
<% hidden_field.user_id, :value => current_user.id %>
<% #survey.questions.each do |q| %>
<li><%= q.content %></li>
<%= question_helper(q) %>
<% end %>
<p><%= f.submit %></p>
<% end %>
And the helper that checks for the type of question it is.
def question_helper(question)
case question.question_type
when 'basic'
return basic_question(question)
when 'fill_in'
return fill_in_question(question)
when 'scale_5'
return "should return a scale of 5"
when 'scale_10'
return "should return a scale of 10"
when 'must_choose_answer'
return question.answers.to_s
when 'just_label'
return " I will be a label"
else
return "Couldn't find in helper"
end
end
You could either go with giving the separate selects different names so that they are submitted separately, or you could submit them all as an array. I would go with the last option.
To submit them as an array, you have to add [] to the end of the select name like this:
question[question_id_#{q.id}][]
Which would end up looking like this:
a << select("question[question_id_#{q.id}][]", :response, (0..30).to_a) + " for #{q.survey.publish_on.strftime('%A')} #{q.survey.publish_on.strftime('%D')} <br />"
I hope that helps.
I have a radio_button_tag in a form, which holds various values for a persons current availability:
Mike Donnall o Available o Out of office o Vacation
So originally you open the form, and select a value, this then sets the value in the Status table for that Person.
However, there's also functionality to re-open the form and update his present status, perhaps from Vacation to Available.
My question is, is there anyway at all that radio button :checked can be modified to accept a custom method, I have found something in a similar posting, but I want the value foe that radio button to be set to the value in the DB.
My code so far, a stab in the dark perhaps:
View:
<% #people.each do |p| %>
<% #statuses.each do |s| %>
<%= "#{p.name}" %>
<%= "#{s.status_name}" -%><%= radio_button_tag ['person', p.id], ['status',
s.id], checked?(p.id) %>
<% end %>
<% end %>
Helper:
def checked?(person)
#person = person
#status = Status.find_by_sql(['select status_id from statuses where person_id = ?, #person])
if #result
return true
end
As you can see Im a bit lost here, but I understand that the method should return the value of the checkbox that needs to be checked, but Im wondering because its a checked functionality, would it only be limited to being a true or false?
So for a persons.status.id check if its true or false.
It seems from your helper's SQL that you the following relationship setup between People and Statuses:
class Person < ActiveRecord::Base
has_one :status
end
class Status < ActiveRecord::Base
belongs_to :person
end
You can access one given person status like this:
person = Person.first
person_status = person.status
Using that knowledge, your desired view outcome becomes quite simple:
<% #people.each do |p| %>
<p><%= "#{p.name}" -%>
<% #statuses.each do |s| %>
<%= "#{s.status_name}" -%>
<%= radio_button_tag ['person', p.id],
['status', s.id],
(p.status == s) ? true : false %>
<% end %>
<% end %>
You can of course extract the logic to a helper, but that doesn't seem necessary.
On a personal note, this isn't the way I'd present the information to user, it' too heavy on information in one line. I suggest you put the person's name in a p tag, and use a ul tag for the statuses.