skip some data from an object rails - ruby-on-rails

Currently i am getting all records from database through this line
#share_requests = CameraShareRequest.all.includes(:user, :camera).decorate
at some points in
<tr>
<td><%= camera_share_request.email %></td>
<td><%= link_to camera_share_request.camera.name, camera_path(camera_share_request.camera) %></td>
<td><%= link_to camera_share_request.user.fullname, user_path(camera_share_request.user) %></td>
<td><%= camera_share_request.message %></td>
<td><%= camera_share_request.share_rights %></td>
<td><%= camera_share_request.user_status %></td>
<td><%= camera_share_request.share_created_at %></td>
</tr>
there few entries where there is no camera_share_request.camera or user i want to skip those entries from my #share_requests object, how it will be possible i tried to do it with unless but failed..

One approach would be:
#share_requests = CameraShareRequest.joins( :user, :camera ).decorate

You can use .not to negate a .where and ignore records without cameras or users:
CameraShareRequest.where.not(user_id: nil, camera_id: nil).includes(:user, :camera).decorate
This will result in SQL looking like:
SELECT "camera_share_requests".* FROM "camera_share_requests" WHERE ("camera_share_requests"."user_id" IS NOT NULL) AND ("camera_share_requests"."camera_id" IS NOT NULL)
If the user_id or camera_id may exist, but the User or Camera has been deleted, you can skip those records when you print your table:
#share_requests.each do |share_request|
next unless share_request.user && share_request.camera
# Print row
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.

Compute multiple distinct averages

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

ActiveModel::MissingAttributeError in rails 3.2.12 with default_scope

We want to use default_scope to be flexible with the columns shown on customer index page. For example, if a user should not see customer phone#, then we remove phone from default_scope and want to leave the phone blank on index page. We got this idea from online and is doing a test. However there is an error missing attribute:phone when phone is selected. Here is our definition for default_scope in customer model:
def self.default_scope
Customer.scoped.select("active,name,sales_id,customer_status_category_id, short_name, zone_id, id, since_date")
end
The index page:
<table>
<tr>
<th>#</th>
<th>ShortName</th>
<th>SinceDate</th>
<th>Phone</th>
<th>Active?</th>
<th>CustomerStatusCategory</th>
<th>Sales</th>
<th>LastContactDate</th>
</tr>
<% #customers.each do |cust| %>
<tr>
<td><%= cust.id %></td>
<td><%= cust.short_name %></td>
<td><%= cust.since_date.strftime("%Y/%m/%d") %></td>
<td><%= cust.phone if cust.phone.present? %></td>
<td><%= cust.active %></td>
<td><%= cust.customer_status_category.name %></td>
<td><%= cust.sales.name %></td>
<td><%= return_last_contact_date(cust.id).strftime("%Y/%m/%d") %></td>
</tr>
<% end %>
</table>
The error is:
ActiveModel::MissingAttributeError in Customerx/customers#index
Showing C:/D/code/rails_proj/engines/customerx/app/views/customerx/customers/_index_partial.html.erb where line #32 raised:
missing attribute: phone
Is it possible to show an empty column by purposely not selecting it in index (or any view page)? If it is possible, is default_scope a right tool to accomplish that? Thanks.

If the product name is nil then use another name?

I am currently developing a cart which will take the id of the CD or a DVD, it then gets the name of the item.
If I use them individually it works fine as I have made the relevant changes in the other files.
The code currently is:
<% if line_item==#current_item %>
<tr id='current_item'>
<% else %>
<tr>
<% end %>
<td><%= line_item.quantity %>×</td>
<td><%= line_item.product.name %></td>
<td><%= line_item.dvd.name %></td>
<td class="item_price"><%= number_to_currency(line_item.total_price, :unit=>'&pound') %></td>
</tr>
If I have a <td><%= line_item.cd.name %></td> line and only add CDs it works fine, and vice-versa with this line <td><%= line_item.dvd.name %></td>.
What I want is it to do a test to see if cd.name is nil and if it is use the dvd.name, but this is not working.
This should work
line_item.cd.try(:name) || line_item.dvd.try(:name)
This code will first try to get CD name and fallback to DVD if either cd or cd.name is nil.
In your Item model, try adding this method:
def cd_or_dvd
line_item.dvd || line_item.cd
end
Than in the view:
<td><%= line_item.dvd.name %></td>

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