Rails finding a value in a table - ruby-on-rails

Is it possible to call the include? function on a whole table, like this?
<% #user.games.each do |g|
##latestround = g.rounds.order('created_at DESC').first
%>
<% if ##latestround.submittedpictures.isFinalPicture.include?(true) %>
<p>FinalPicture has been played!</p>
<% end %>
<% end %>
The problem i'm getting is that It only works when I put a block on submittedpictures and then loop through each record of this table. However I want to look through the whole table in one go and see if the column 'isFinalPicture' includes a value with 'false'.
Any ideas?
The following snippet works but its not the way i want it (I would get more lines if the round happens to have more 'true' FinalPictures)
<% ##latestround.submittedpictures.each do |s| %>
<% if s.isFinalPicture == true %>
<p>Final Picture has been played!</p>
<% end %>
<% end %>

You could make a scope for it like
class SubmitedPricture << ActiveRecord::Base
scope :final_pictures, where('isFinalPricture = ?', true)
end
then you could see if there is any with only one query
latestround.submittedpictures.final_pictures.any?
Also you should follow the conventions of Rails in naming your Models and everything else. Like submittedpictures should be submitted_pictures

Related

Rails: show post when attributes is set to true

I am facing a weird bug and unfortunately I don't know how to investigate about it.
I am rendering certain pins on my homepage when the integer => pinoftheday is set to true. I am manually setting some pins to true.
For some pins its working well and they are appearing on the homepage, some others just don't. Btw, I am checking in my console and they are correctly set to true.
Here is a bit of code:
<% #pins.each do |pin| %>
<% if pin.pinoftheday %>
(...) some informations about the pin
<% end %>
<% end %>
Any ideas how I could check why some pins are not rendering? I am not writting any tests for now... I know this is stupid but I just did not learnt testing for rails.
Thank you.
EDIT: Yes, in my code it's a pin model. I wanted to used post to make it clearer. Figured it was not :) - Edited it to the correct model: pin.
Try the below code.
<% #postss.each do |post| %>
<% if post.pinoftheday %>
(...) some informations about the pin
<% end %>
<% end %>
Your problem is that you've defined a local variable in your block, and are referencing another:
<% #postss.each do |post| %>
<% if post.pinoftheday %>
...
<% end %>
<% end %>
--
You'd be better using a scope:
#app/models/post.rb
class Post < ActiveRecord::Base
scope :pin_of_the_day, -> { where pinoftheday: true }
end
You'll also do well to make your pinoftheday column boolean. If you're referencing 1 = true; 0 = false, Rails handles that with a tinyint in your db, calling true/false as boolean logic. Instead of referencing the integer as a number, you can call true etc.
The above will allow you to call:
#app/controllers/your_controller.rb
class YourController < ApplicationController
def index
#postss = Post.pin_of_the_day
end
end
This will remove the inefficient conditional logic (<% if ...):
<% #postss.each do |post| %>
...
<% end %>
If I understood your code then will below:
<% #postss.each do |pin| %>
<% if pin.pinoftheday.nil? %>
(...) some informations about the pin
<% else %>
(...) some informations about the pin
<% end %>
<% end %>
Hope will help you

Get model type from each loop

I'm combining two models in my controller, and trying to print them in a similar fashion, but I'd like to do an if statement in an each loop to distinguish one model from the other. My models are comments and likes.
In the controller:
#items = (#user.likes + #user.comments).sort{|a,b| a.created_at <=> b.created_at }
In my view:
<%= #items.each do |item| %>
<% item.name %>
<% end %>
I need an if statement to say IF comment or IF like in the each loop. I've been drawing a blank on the situation.
Assuming you have model Like and Comment
<%= #items.each do |item| %>
<% if item.instance_of?(Like) %>
Something for likes
<% elsif item.instance_of?(Comment) %>
Something for comments
<% end %>
<% end %>
You could do item.class.name as Nithin mentioned, and it'll work fine. However, the more idiomatic way is to use instance_of?. So it'd look like this:
if item.instance_of?(Post)
# do something
elsif item.instance_of?(User)
# do something else
end
Note you're not passing in 'Post' or 'User' as strings - you're passing in the Ruby class constants themselves.
On this topic, it's also worth knowing about Ruby's is_a? and kind_of? methods which work similar to instance_of? but return true if the instance you're testing is an instance of a subclass of the parameter you pass in (more info at Ruby: kind_of? vs. instance_of? vs. is_a?).
What you need to do is to check for the class of the Item of interest.
Basically, each object belongs to a class, and the class name of a comment will be a Comment while that of a like will be a Like.
So, in the loop, check for the class name as:
<%= #items.each do |item| %>
<% if item.class == Comment %>
...comments here
<% elsif item.class == Like %>
...likes here
<% end %>
<% end %>

Can I query the current scope(s)?

My collections model has a scope like this
scope :got, -> { where(status: 'Got') }
I have a link to an index as follows
<%= user_collections_path(#user, got: true) %>
Thanks to the has_scope gem that creates an index of the user's collections where the status: is 'Got'. the path is
users/user1/collections?got=true
In that index view I want to be able to write something like
<% if status: 'Got' %>
You have these ones
<% end %>
But no matter how I write it I can't seem to query the scope that was passed in the link. Is there a standard way of doing this?
You can do as following:
<% if params[:got].to_s == 'true' %>
You have these ones
<% end %>
But this forces you to use true as value for params[:got]. Maybe this is better:
<% if params[:got].present? %>
You have these ones
<% end %>
But this will work with params like:
users/user1/collections?got=true,
users/user1/collections?got=false,
users/user1/collections?got=NOPE,
etc.
Actually, the has_scope gem provides a method current_scopes that returns a hash (key = scope, value = value given to the scope) in the corresponding views. You should be able to do like this:
<% if current_scopes[:got].present? %>
You have these ones
<% end %>

How to return ActiveRecord Association Proxy on ERB

so I have a standard has_many through association in my models, very similar to the question here: Loop through ActiveRecord::Associations::CollectionProxy with each
I used the advice in that problem but I think I am having some trouble getting it through on my ERB file so that it shows up in my app. At the moment I have the following:
<%= #memberships.map do |a| %>
<%=a.name%>
<% end %>
In this scenario, the membership model is the one through which users and organizations have many though (#memberships = #user.organizations). So the #memberships.class returns
ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_Organization
on the rails console. So the moment, in the browser the code returns on a page where the user is in two orgs:
orgone orgtwo["\n", "\n"]
I just don't know how to manipulate the proxy classes to return what I want. Thanks!
UPDATE:
I figured it out, I had to remove the = at the top of the block, and I added some styling with a comma:
<% #memberships.map do |a| %>
<h3><%=a.name %> <%= ", " unless a == #memberships.last %></h3>
<% end %>
If you want to print the name of each membership, what you want is
<% #memberships.each do |membership| %>
<%= membership.name %>
<% end -%>
The <% prefix in ERB executes code without appending the results to the output buffer, while the <%= prefix outputs the string representation of the result of the expression. Since each returns an enumerator, a <%= will return the string representation of the enumerator which is something like #<Enumerator:0xDEADBEEF.

Test ownership in a helper

I have this block in my views:
<% video.members.each do |p| %>
<% if p.id == current_user.id %>
<%= "paid" %>
<% end %>
<% end %>
Basically I'm trying to work out if a member has paid for a video based on whether the id's match.
Maybe this a really bad way of doing it, which case I'd be happy to try and different method.
Assuming it is an ok way of checking this, how could I write a similar statement but as a helper method? I've tried, but it seems you can't write the same logic in helpers as the block just spits out the full array and not the id, meaning it doesn't work.
You should do this instead:
<% if video.members.exists?(id: current_user.id) %>
<%= 'Paid' %>
<% end %>
This will generate a single query to test if the video has been paid by the current_user ;-)
In a helper:
# application_helper.rb
def display_paid_or_not(video)
return '' if video.blank? # similar to .nil?
video.members.exists?(id: current_user.id) ? 'Paid' : ''
end
# in view
<%= display_paid_or_not(video) %>
Hope this helps!

Resources