Rails mailer template calculation - ruby-on-rails-3

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 %>

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.

How do I group radio buttons for separate fields?

I have a rails app that gives users assignments and prompts them via email to come back and note that their assignment is completed or take some other action. I have three different actions (remind me later, choose a different assignment, or get help from a coach) which are represented by three radio buttons. How do I group these so that the user can only choose one of the three actions at a time?
<%= form_for(#assignment, :url => user_assignment_path(#user, #assignment)) do |a| %>
<%= a.radio_button :next_reminder_date, value: (Date.today + 2) %> <h3>Remind me again in 2 days.</h3><br>
<%= a.radio_button :coach_requested, true %> <h3>I'm stuck! Have a coach contact me.</h3><br>
<%= a.radio_button :abandoned, true %> <h3>This sucks. Give me another assignment.</h3><br>
<%= a.submit "Update assignment", class: "btn btn-primary btn-large" %>
<% end %>
I think you have two options. One would be to set the values using JavaScript. When any of the values is set, you can reset the other values. This won't work if a user doesn't have JavaScript so I'd recommend option 2.
Use something like this in your View:
radio_button_tag :next_action, :next_reminder_date
radio_button_tag :next_action, :coach_requested
radio_button_tag :next_action, :abandoned
Then in your Controller:
case params[:next_action]
when :next_reminder_date
#assignment.next_reminder_date = Date.today + 2
when :coach_requested
#assignment.coach_requested = true
when :abandoned
#assignment.abondoned = true
end
I hope that helps.

howto globally substitute nil values with a specific character (e.g. "-") in rails views

I guess it's a simple question, but how can I replace nil values in generell in my views.
I want to avoid having something like
<% unless value == nil %>
<%= value %> Ohm
<% else %>
<p>-</p>
<% end %>
Where is the best place to handle this?
I generally put little formatters like this in a helper:
module ResistorsHelper
def format_resistance(resistance)
resistance.nil? ? content_tag(:p, '-') : "#{resistance} Ohm"
end
end

need to create a helper for 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.

Cut off text exceeding a certain length

I have a list with texts with lengths ranging from 1 character to several thousands. I want to cut off all texts exceeding 255 characters. How can I do that?
Do I have to check the length of each String and then cut it with (255) or is there a more elegant expression?
Edit: like this
<% IF STRLEN( wa_comm-text ) > 255. %>
<%= wa_comm-text(255) %> ...
<% ELSE. %>
<%= wa_comm-text %>
<% ENDIF. %>
this is BSP
Thanks in advance
The other option is:
<%
data: ls_text(255) type c.
ls_text = wa_comm-text.
%>
<%= ls_text %>
Because you obviously cannot use substrings on strings, and if they are shorter, you will get a runtime error.
I created for this a 'string solutions' class called zss, with a static method that will cut off a given string and the given length.
Then you can just do something like this:
<%= zss=>left( s = wa_comm-text cutoff = 255 ). %>
or even a more specific method
<%= zss=>left255( wa_comm-text ). %>
Just as an option:
<%= CONV char255( wa_comm-text ) %>
inline conversion and trimming to target type is done here.