need to create a helper for rails 3 - ruby-on-rails-3

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.

Related

Rails form - search engine

I try to create simple search engine but I meet some problmes. I have several search_field in my form and if either is empty should returns all objects. Otherwise when it has any content it should be selected by that content. Below is my sample form:
<%= form_for :product, url: products_path, method: :get do |form| %>
<%= form.search_field :brand %>
<%= form.search_field :model %>
<%= form.search_field :price_from %>
<%= form.search_field :price_to %>
<%= form.submit 'Submit' %>
<% end %>
my model method:
def self.search(search)
where(brand: search[:brand]).where(model: search[:model]).where("price >= ?", search[:price_from]).where("price <= ?", search[:price_to])
end
But the above piece of code is wrong because if I leave some field empty it is treated directly as empty string instead of ignore this field and final result is not correct.
Summary this form should work similarly to filter on online store
You'd could do something like this
def self.search(search)
results = all
results = results.where(brand: search[:brand]) if search[:brand]
results = results.where(model: search[:model]) if search[:model]
results = results.where("price >= ?", search[:price_from]) if search[:price_from]
results = results.where("price <= ?", search[:price_to]) if search[:price_to]
return results
end
Good luck.

Rails group_by and in_groups_of error

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.

Rails 3 displaying count inside a loop

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 :)

Rails mailer template calculation

I am new to rails and am writing a daily report email template.
I am Outputting unique visitors, and calculating the difference between the 2 and displaying that as well with a + or - sign depending on if its positive or negative.
Is there a better way to do this? Should I not be doing math inside the view?
Unique Visitors: <%= number_with_delimiter(#stats["unique_visitors"]) %>
<% uniquediff = #stats["unique_visitors"] - #stats["unique_visitors_yesterday"] %>
(<% if uniquediff > 0 then %> + <% else %> - <% end %> <%= uniquediff %>)<br />
Try:
("+" if uniquediff>=0)+uniquediff.to_s
.to_s turns uniquediff to a string, and the ("+" if uniquediff>=0) bit evaluates to "+" if uniquediff is greater than or equal to zero, and nothing otherwise.. and you will already have a "-" if it is negative.
=]
How about this:
<% unique_diff = #stats['unique_visitors'] - #stats['unique_visitors_yesterday'] %>
<%= "Unique Visitors: #{number_with_delimiter(#stats['unique_visitors'])} #{'+' if unique_diff > 0}#{unique_diff}" %><br/>
It's recommended to do logical stuff in HELPER(and it's what a helper should do).
# In helper, eg. application_helper.rb
def unique_diff(stats)
unique_diff = stats['unique_visitors'] - stats['unique_visitors_yesterday']
(unique_diff > 0) ? "+#{unique_diff}" : "#{unique_diff}"
end
# In view
Unique Visitors Diff: <%= unique_diff #stat %>

How to create own block helper with two or more nested children?

I'd like to to something nested like that in my views:
<%= helper_a do |ha| %>
Content for a
<%= ha.helper_b do |hb| %>
Content for b
<%= hb.helper_c do |hc| %>
Content for c
... and so on ...
<% end %>
<% end %>
<% end %>
To get for example this:
<tag_a>
Content for a
<tag_b class="child_of_tag_a">
Content for b
<tag_c class="nested_child_of_tag_a child_of_tag_b">
Content for c
</tag_c>
</tag_b>
</tag_a>
This means, each level has access to some information of the level above (that's why they are nested and not completely autonomous methods)
I know how to create a simple helper:
def helper_a(&block)
content = capture(&block)
content_tag :tag_a, content
end
And I know I can pass my arguments to the capture to use them in the view, so something like this to get live up the |ha| of my example
def helper_a(&block)
content = capture(OBJECT_HERE, &block)
content_tag :tag_a, content
end
But where do I define this OBJECT_HERE, especially the class for it, and how can this go on nested with multiple levels capturing each block?
I came up with a couple solutions, but I'm far from being an expert in the Rails templating system.
The first one is using an instance variable :
def helper_a(&block)
with_context(:tag_a) do
content = capture(&block)
content_tag :tag_a, content
end
end
def helper_b(&block)
with_context(:tag_b) do
content = capture(&block)
content_tag :tag_b, content
end
end
def helper_c(&block)
with_context(:tag_c) do
content = capture(&block)
content_tag :tag_c, content
end
end
def with_context(name)
#context ||= []
#context.push(name)
content = yield
#context.pop
content
end
which is used this way :
<%= helper_a do %>
Content for a
<%= helper_b do %>
Content for b
<%= helper_c do %>
Content for c
... and so on ...
<% end %>
<% end %>
<% end %>
And the other solution, which passes the context at each step :
def helper_a(context = [], &block)
context = capture(context.push(:tag_a), &block)
content_tag(:tag_a, content)
end
def helper_b(context = [], &block)
context = capture(context.push(:tag_b), &block)
content_tag(:tag_b, content)
end
def helper_c(context = [], &block)
context = capture(context.push(:tag_c), &block)
content_tag(:tag_c, content)
end
which is used this way :
<%= helper_a do |context| %>
Content for a
<%= helper_b(context) do |context| %>
Content for b
<%= helper_c(context) do |context| %>
Content for c
... and so on ...
<% end %>
<% end %>
<% end %>
But I'd really advise against using either of these solutions if all you're doing is CSS styling and/or Javascript manipulation. It really complicates the helpers, is likely to introduce bugs, etc.
Hope this helps.