Compute multiple distinct averages - ruby-on-rails

I'm fairly new to rails, and am still getting used to putting together methods. I'm currently trying to create a method that averages distinct data from multiple columns. I'd like to do it all in one method so that I can display the information easily in an html table.
Currently I have this in my model:
def averagedonate
scores.group(:donatedate).average('donateamount')
scores.group(:donatedate).average('rating')
end
I'd like to be able to use them in a table like this:
<% #averagedonate.each do |donatedate, donateamount, rating| %>
<tr>
<td><%= donatedate %></td>
<td><%= donateamount %></td>
<td><%= rating %></td>
</tr>
How do I change my averagedonate method to do this? Thanks in advance!

I haven't tested, but something to this effect should work
def averagedonate
scores.select("
AVG(donateamount) as avg_donateamount,
AVG(rating) as avg_rating,
donatedate
")
.group(:donatedate)
end
Then use it like this
<% #averagedonate.each do |item| %>
<tr>
<td><%= item.donatedate %></td>
<td><%= item.avg_donateamount %></td>
<td><%= item.avg_rating %></td>
</tr>
<% end %>

Related

Rails: Sum column by group

I created this code that pulls the information I need.
def index
#votes = Vote.all
#originalitysum = Vote.group(:widget_id).sum(:originality)
end
It returns a hash:
{188=>5, 160=>2}
I now need to match the key to the widget_id and return the value. I.E:
If the widget_id is 188 return 5.
<% #votes.group(:widget_id).each do |vote| %>
<tr>
<td><%= vote.widget.name %></td>
<td><%= vote.widget.store %></td>
<td><%= %></td> <!-- This needs to be the total Originality -->
<td><%= vote.interest %></td>
<td><%= vote.rating %></td>
</tr>
<% end %>
I'm open to changing this if some other way makes more sense.
You can get the originality sum with #originalitysum[vote.widget.id]
Figured it out.
Controller
def index
#votes = Vote.all
#originalitysum = Vote.select([:widget_id, :originality]).group('widget_id').sum(:originality)
#votecount = Vote.group(:widget_id).count(:originality)
#votes = Vote.select(:widget_id,
"SUM(originality) as originality_sum",
"SUM(interest) as interest_sum",
"SUM(rating) as rating_sum").group(:widget_id).order("rating_sum DESC")
end
The view
<% #votes.group(:burger_id).each do |vote| %>
<tr>
<td><%= vote.widget.name %></td>
<td><%= vote.widget.store %></td>
<td><%= vote.originality_sum %></td>
<td><%= vote.interest_sum %></td>
<td><%= vote.rating_sum %></td>
</tr>
<% end %>
Thanks to this answer in this link, I was able to parse it together.
Group by a column and then get the sum of another column in Rails
The added bonus is that it allowed me to easily sum the other columns as well.

Using .blank? with postgres

Hi chaps and chappettes.
<tbody>
<% #orders_outstanding.limit(5).each do |order| %>
<% if order.completed_at.blank? && order.due_date.present? %>
<tr>
<td><%= order.order_number %></td>
<td><%= order.customer %></td>
<td><%= order.printer %></td>
<td><%= order.quantity %></td>
<td><%= order.due_date %></td>
</tr>
<% end %>
<% end %>
</tbody>
I'm using this little bit of code to display my next five orders due to ship. It's showing up in my development environment preview (puma/sqlite) but not on heroku (postgres). Is there any reason heroku doesn't like that formatting?
Thanks
I would put the conditions in the controller to make sure you have 5 that match your conditions:
#orders_outstanding = Order.where(completed_at: nil).where.not(due_date: nil).order("due_date")

Rails 3 each do ignore nil values

I am building an html table that should include name, rating1, rating2, and rating3. rating 1-3 come from different models than name.
resources :names do
resource :rat1,:rat2,:rat3
end
Inside of my html table I'd like to include the ratings from within each of these tables but I would like to automatically skip over or ignore tables that are nil. This is because :names may only have a :rat1 and not a :rat2 or :rat3. My view should look something like this.
<table>
<thead>Name</thead>
<thead>Rating 1</thead>
<thead>Rating 2</thead>
<thead>Rating 3</thead>
<% #names.each do |name| %>
<tr>
<td><%= name.nametext %></td>
<td><%= name.rat1.rating %></td>
<td><%= name.rat2.rating %></td>
<td><%= name.rat3.rating %></td>
</tr>
<% end %>
</table>
Except that if name.rat1 is nil it will either a.) replace the value with N/A OR b.) it will leave this field blank and move on to the next.
What is the cleanest way to do this?
::UPDATE::
So my issue is that the name.rat1 is nil and the name.rat1.rating is an undefined method of a nil class so both of these options will throw the same undefined method of a nil class error regardless of the || or helper method. At least thats what my current tests are showing. Any other options? or different workarounds? I'd like to avoid having to put a validation loop like this for every rat1-3
<% unless name.rat1.nil? %>
<%= name.rat1.rating %>
<% end %>
There has to be a simpler way.
I would probably create a helper method in names_helper.rb
def show_rating(rating)
if rating.present?
rating
else
"default value"
end
end
Then use it in the view:
<%= show_rating name.rat1.rating %>
OFFTOPIC Your table structure is wrong. It should have <thead><tr><th>Name</th><th>Rating1</th>..so on..</tr></thead>
So, in your case you can use the condition while rendering the rating values as:
<table>
<thead>
<tr>
<th>Name</th>
<th>Rating 1</th>
<th>Rating 2</th>
<th>Rating 3</th>
</tr>
</thead>
<tbody>
<% #names.each do |name| %>
<tr>
<td><%= name.nametext %></td>
<td><%= name.rat1.rating || 'N/A' %></td>
<td><%= name.rat2.rating || 'N/A' %></td>
<td><%= name.rat3.rating || 'N/A' %></td>
</tr>
<% end %>
</tbody>
</table>

Displaying data from a collect in rails

I currently have models that can be described as follows:
Songs can have many setlists through Allocations
Allocations belong to songs and setlists
Setlists can have many songs in them through allocations
Songs have a title, artist, and a musical key.
Basically I'm setting up the new setlist view where a musician can select any existing songs from the library to add to a setlist. I want to do something along these lines:
<thead>
<th>Title</th>
<th>Artist</th>
<th>Root Key</th>
</thead>
<tbody>
INSERT CODE HERE TO DISPLAY DATA
</tbody>
At the moment I'm using the following code to get the data but I don't know if there's a way to separate it out into the relevant cells in the table:
<% songs = Song.all.collect {|s| [ s.title, s.artist, s.key ] } %>
<% songs.sort! %>
I'm not sure if this is this is the best way to go about doing this so if anyone could suggest an alternative that would be fantastic too. Thanks in advance!
Fetching data is controller's responsibility.
def index
#songs = Song.select([:title, :artist, :key]).all
end
And view:
<tbody>
<% #songs.each do |song| %>
<tr>
<td><%= song.title %></td>
<td><%= song.artist %></td>
<td><%= song.key %></td>
</tr>
<% end %>
</tbody>
I managed to solve the problem as follows:
<tbody>
<% songs.each do |n| %>
<tr>
<td><%= n[0], '#' %></td>
<td><%= n[1], '#' %></td>
<td><%= n[2], '#' %></td>
</tr>
<% end %>
</tbody>
I'm still not sure whether or not this is best practice or not so if anyone know of a better way please let me know. Thanks :)

How do I output name instead of ID?

Rails newbie here! I have a has_many_and_belongs_to_many relationship between items and builds.
In the code provided below, the ID of the items are being displayed instead of the name of the item with that ID. How do I display the name of the item?
<% current_user.builds.each do |build| %>
<tr>
<td><%= build.hero.name%></td>
<td><%= build.user.email%></td>
<td><%= build.name %></td>
<td><%= build.starting_items %></td>
<td><%= build.early_items %></td>
<td><%= build.core_items %></td>
<td><%= build.situational_items %></td>
</tr>
<% end %>
If you mapped association (has_one) in model with Hero and User, then probably you can use following code:
build.hero.field_name # Where field_name is column name from Hero Model
Please let me know if this will work for you or not.

Resources