At the moment i'm playing around with Rails to get the hang of it and coding in general. Therefore I created my first rails app in which I want to display my games (from the game database) on one of the pages and sort them by a variable calculated within the each function. My view page looks like this (simplified):
<% #games.sort_by{|game| ???}.each do |game| %>
<p>Userexp: <%= game.userexp1 %></p>
<p>Userexpscore: <% if (game.userexp1 <= 60) %> <%= #UserexpScore = 1 %>
<% elsif (game.userexp1 > 60) %> <%= #UserexpScore = 2 %> = 2 <% end %></p>
<p>Price: €<%= game.price %></p>
<p>Pricescore: <% if (game.price <= 20) %> <%= #PriceScore = 2 %>
<% elsif (game.price > 20) %> <%= #PriceScore = 1 %> <% end %></p>
<p>Finalscore: <%= #FinalScore = #UserexpScore + #PriceScore %></p>
<% end %>
I get how i can order them by game.userexp1 or game.price but I can't figure out if it is possible to sort them by #FinalScore (without also putting the userexpscore and pricescore in the database). I was wondering if this is possible and if yes how I can do that.
Thanks in advance!
View is not proper place for business logic.
You can move score calculating logic into model, e.g.:
class Game < ActiveRecord::Base
def userexp_score
userexp1 <= 60 ? 1 : 2
end
def price_score
price <= 20 ? 2 : 1
end
def final_score
userexp_score + price_score
end
end
Then in view
<% #games.sort_by(&:final_score).each do |game| %>
<p>Userexp: <%= game.userexp1 %></p>
<p>Userexpscore: <%= game.userexp_score %></p>
<p>Price: €<%= game.price %></p>
<p>Pricescore: <%= game.price_score %></p>
<p>Finalscore: <%= game.final_score %></p>
<% end %>
I suggest you read about MVC and separation of concerns
Related
I have 100 shoes with shoe names. I don't want to display all 100 in a row, I want to display 5, then a green box, then the next 5, and the same green box... but there is something wrong with my code.
<% #shoes.each.with_index(1) do |shoe, index| %>
<% while index < 101 do %>
<%= shoe.name %>
<% if index % 5 == 0 %>
<%= Green Box %>
<% end %>
You're looking for in_groups_of(x)
<% #shoes.in_groups_of(5) do |shoe_groups| %>
<% shoe_groups.each do |shoe| %>
<%= shoe.name %>
<% end %>
<%= 'Green Box' if shoe_groups.size % 5 == 0 %>
<% end %>
Your syntax is wrong in several places - the enumerator is wrong, you are missing several end statements. Also, even though index is not a reserved word, the generally accepted style for an index is a single-letter variable like i. It should be
<% #shoes.each_with_index(1) do |shoe, i| %>
<% while i < 101 do %>
<%= shoe.name %>
<% if i % 5 == 0 %>
<%= Green Box %>
<% end %>
<% end %>
<% end %>
(But personally, I would not do the index < 101 block in the view - I would make sure that the controller that generates #shoes and sends it to the view only sends 100 elements in the array)
I'm trying to create a timeline for #challenges. For those challenges that have a :deadline I want them to be organized on the timeline according to their :deadline and for those challenge that have a :date_started I want them to be organized on the timeline according to their :date_started.
If a challenge has a :deadline then date_started is nil and vice versa.
example
2016
February
CHALLENGE 1 (Deadline: 1st)
CHALLENGE 2 (Date_Started: 3rd)
CHALLENGE 3 (Deadline: 18th)
controller
#challenges = current_user.challenges
#challenges_timeline = #challenges.group_by { |t| t.deadline.beginning_of_year + t.date_started.beginning_of_year }
view
<% #challenges_timeline.sort.each do |year, challenges| %>
<%= year.strftime('%Y') %>
<% challenges.group_by { |t| t.deadline.beginning_of_month + t.date_started.beginning_of_month }.sort.each do |month, challenges| %>
<%= month.strftime('%B') %>
<% for challenge in challenges %>
<% if challenge.deadline.present? %>
<%= challenge.deadline %>: <%= challenge.action %>
<% end %>
<% if challenge.date_started.present? %>
<%= challenge.date_started %>: <%= challenge.action %>
<% end %>
<% end %>
<% end %>
<% end %>
Change your schema:
If the two dates negate each other, perhaps you should have just one date field, and another field to show whether the date is the beginning or the end. That would allow you to group on the database level, saving some processing time.
Add instance method
A simple instance method such as
def timeline_date
deadline || date_started
end
would allow simple grouping such as
challenges.group_by { |c| c.timeline_date.beginning_of_month }
Use || directly in the group_by block.
The following loop goes through the sales column and lists all 4 existing product values, like 19.99 19.99 3.99 3.99 to the corresponding user id.
<% #sales.each_with_index do |sale, index| %>
<% if current_user.id == sale.user_id %>
<% price = Warehouse.where(:product => sale.product).pluck(:mrr) %>
<%= value = price.split(',').join('.').to_f %>
<% else %>
<% end %>
Now I want to save the results/values into a new global variable and add up each out of "value". So the result of 19.99 19.99 3.99 3.99 should be 47.96.
I'm completely lost. Any Ideas?
You could do something like this:
<% total = 0 %>
<% #sales.each_with_index do |sale, index| %>
<% if current_user.id == sale.user_id %>
<% price = Warehouse.where(:product => sale.product).pluck(:mrr) %>
<%= value = price.split(',').join('.').to_f %>
<% total += value %>
<% end %>
<% end %>
<%= "Total is #{total}" %>
It is highly questionable to have code like this in the view though. You could get prices and calculate totals in your controller instead.
Also note that you are missing an end. I changed the unneeded else to an end.
In your controller you can create a instant variable prefixed by # so it can be used throughout your view
For example in your controller
#total_value = 0
And in your view
<%#sales.each_with_index do |sale, index| %>
<% if current_user.id == sale.user_id %>
<% price = Warehouse.where(:product => sale.product).pluck(:mrr) %>
<%= value = price.split(',').join('.').to_f %>
<% #total_value += value %>
<% else %>
<% end %>
You shouldn't add that kind of logic in your view. Create a view object class (that the controller instantiates) too handle all of this. You also probably can do something like:
user.sales.each do |sale|
total += find_price(sale)
# do more stuff
end
If you are asking 'if current_user.id == sale.user_id' then you most likely doing it wrong.
In that view object you could have a hash that has all the prices you want to show and iterate over that in your view.
In code:
<% #offers.each do |offer|%>
<%= offer.percentageOff%> <b>% OFF on order of</b>
<%= image_tag('1407951522',:size=>'10x10',:alt=>'Rs.')%>
<%= offer.amountforDiscount%>
<%= button_to 'Delete',{:action=>'destroy',:id=>offer.id},class: "" %>
<% end %>
I am new in rails. I want to show all the offers in a numbered list, I can't use database table because id is not in order. For example:
30 % OFF on order of Rs.2000
13 % OFF on order of Rs.1000
How do i achieve this?
Easiest way if you don't want to use each_with_index then You can define variable #count=0 and display, as loop occur it will be increment by 1
<% #count = 0 %>
<% #offers.each do |offer|%>
<%= #count += 1 %> #I guess you want this to show Sr.No
...... # your code
<% end %>
each_with_index way :
<% #offers.each_with_index do |offer, index|%>
<%= index + 1 %> # index starts from 0, so added 1 to start numbering from 1
...... # your code
<% end %>
New to Rails! I have products which are associated to a campaign. Each #product has a .price and .orders_count associated to it.
What I wanted to do is multiply the .price with .orders_count for each #product, and add them all up to get a total cost for the #campaign.
Being new to Rails, wasn't sure how to do the write syntax and had the following in the view. This does the first piece, but does not add them all up at the end. Thanks for the help!
<% #products.each do |p| %>
<% if p.orders_count? %>
<%= (number_to_currency((p.price) * p.orders_count)) %>
<% end %>
<% end %>
Try setting a variable to keep track of the sum of all products, and add the product to it each time through the loop. Try this:
<% sum = 0 %>
<% #products.each do |p| %>
<% if p.orders_count? %>
<% product = (number_to_currency((p.price) * p.orders_count)) %>
<% sum += product %>
<%= product %>
<% end %>
<% end %>
The sum is: <%= sum %>