Retrieve and display Active Record data - ruby-on-rails

I would like to show a number of things on my homepage, all being pulled from different tables in the database and just wanted to see the best way to do it.
Reading through https://guides.rubyonrails.org/v2.3.11/active_record_querying.html, I was able to get it to show the correct details, but is this the best way to do it? Are there performance issues to come with this method?
<% about = Page.find(1) %>
<h1 class="title"><%= about.title %></h1>
<% unless about.subtitle.blank? %>
<h2 class="subtitle"><%= about.subtitle %></h2>
<% end %>
<p><%= about.body %></p>
And on a similar topic, what is the best way to iterate and display data? This is what I would like to achieve:
<div class="tabs">
<ul>
<% Chapter.all.each do |c| %>
<li><a><%= chapter.title %></a></li>
<% end %>
</ul>
</div>
Any tips greatly appreciated!

To achieve this
<div class="tabs">
<ul>
<% Chapter.all.each do |c| %>
<li><a><%= c.title %></a></li>
<% end %>
</ul>
</div>
There is a few things that must be present:
First step
You need to have a model or data set that represent your data, example you might have a Person.rb file with name and hair color as properties. That can be your model, all it is doing is defining a dataset.
class Person < ApplicationRecord
scope :latest_Person, -> { order(date: :desc) }
validates :name, presence: true, length: { minimum: 5 }
validates :haircolor, presence: true
end
Second step
You need to declare or instantiate that model in your controller class, example you might need to show a list of persons in a particular order. That can be handled using scopes. Example
def persons
# Render all persons
#persons_all = Person.latest_Person
end
Third step
Calling the declared object from the controller class in the view. Basically all you are doing is referencing the declared object. Example
<% if #persons_all.empty? %>
<h2>No persons available</h2>
<% else %>
<% #persons_all.each do |p| %>
<p><%= p.name %></p>
<p><%= p.haircolor %></p>
<% end %>
<% end %>
Mark as answer is it helped, thank you.

Related

Make shuffle order persistent across loops (Ruby on Rails)

I need to access the same random shuffling across two different loops on the same ERB page.
Context:
I have questions which have five choices of which one is TRUE for choices.is_correct.
My current ERB (below) successfully displays:
1) Grouped by usage
2) All available questions (shuffled)
3) And all five choices (also shuffled)
What I'd like to add is a separate loop (directly after in the same ERB), which gives:
1) Same grouping by usage
2) Same order of available questions (eg, same shuffle order)
3) The correct answer choice (eg, answer "B" = referencing the same shuffling)
Assigning the question or choice shuffling globally would not work, as I need it to be randomized on each page load.
Current ERB (currently shuffles each loop separately)
<%= #exam.name %>
<br />
<% alpha_numbers = ("A".."Z").to_a %>
<% #book_questions_by_usage.each do |usage, question| %>
<h4><%= usage if usage %></h4>
<% question.shuffle.each_with_index do |question, i| %>
<%= i+1 %>: <%= question.name %>
<ol type="A">
<% question.choices.shuffle.each_with_index do |choice, index| %>
<% choice.alpha_order = alpha_numbers[index] %>
<li><%= choice.name %></li>
<% end %><br />
</ol>
<% end %>
<% end %>
<% #book_questions_by_usage.sort.each do |usage, question| %>
<h4><%= usage if usage %></h4>
<% question.shuffle.each_with_index do |question, i| %>
<%= i+1 %>: <%= question.name %>
<ol type="A">
<% question.choices.select { |choice| choice.correct }.shuffle.each_with_index do |choice, index| %>
<% choice.alpha_order = alpha_numbers[index] %>
Correct Answer: <b><%= choice.alpha_order %>. <%= choice.name %></b>
<% end %><br />
</ol>
<% end %>
<% end %>
question.rb
class Question < ApplicationRecord
before_validation :assign_questionable
belongs_to :questionable, polymorphic: true
has_many :choices, :dependent => :destroy
accepts_nested_attributes_for :choices, allow_destroy: true
choice.rb
class Choice < ApplicationRecord
belongs_to :question
I've spent hours looking into possible solutions with no success so far. Any help is much appreciated!
How about you don't shuffle in the view, but in the controller. Save the shuffled array in an instance method and then use it in the view where you need it.

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

Create a Ruby feed of two un-related tables

I'm creating an app that has two sets of content that's unrelated.
The first is Questions and Answers (Q&As) where a user can ask a question and the community can answer.
The second is an RSS like feed where an article is posted and links to a 3rd party site.
I'd like to create a 'Feed' so when the user logs in, they see the latest of the Q&As and the latest news all mixed together. I've got it working now where they aren't mixed together.
So two questions, how do i combine the two data sets? And what is the code to make it viewed given it's different content in each table.
Here is my code:
app>models>feed.rb
class Feed < ActiveRecord::Base
validates :name, :url, :description, :source, presence: true
end
app>models>question.rb
class Feed < ActiveRecord::Base
belongs_to :user
has_many :answers, dependent: :destroy, foreign_key: "id"
end
app>controllers>feeds_controller.rb
def index
#feeds = Feed.where("created_at >= ?", Date.today)
#questions = Question.where("created_at >= ?", Date.today)
end
app>views>feeds>index.html.erb
<% #feeds.each do |feed| %>
<h3><%= feed.name %></h3>
<p><%= feed.source %></p>
<p> <%= feed.created_at.strftime("%b %d, %Y") %> </p>
<%= link_to image_tag(feed.image.url(:medium)), feed.url %><br>
<%= truncate(feed.description, length: 50) %><br>
<% end %>
<% #questions.each do |question| %>
<tr>
<td><h1><%= link_to question.question , question_path(question) %></h1></td>
<td><p>Posted by: <%= question.user.name %></p></td>
<td> <p><%= question.created_at.strftime("%b %d, %Y") %> </p></td>
<td><p>Number of answers: <%= question.answers.count %> </p></td>
</tr>
<% end %>
I don't think join works given they have different data. Any suggestions on how to combine feed and questions into one stream with the most recent at the top? (like a facebook feed).
thanks for your help!
I'd suggest this... which is doing array sorting, but I think you don't have a choice with two unrelated object types.
#combined = (#feeds.to_a + #questions.to_a).sort{|a,b| b.created_at <=> a.created_at}
Then in the view...
<% #combined.each do |combined| %>
<%= render combined %>
<% end %>
The beauty of the render is that it will render a partial appropriate to the type of object. If combined s a Feed object the partial used will be feeds/_feed but if it's a Question object it will use the partial questions/_question
I was able to get this working with a few small changes. Rather than rendering the partial I did the following
<% #combined.each do |combined| %>
<% if combined.is_a?(Feed) %>
<h3><%= combined.name %></h3>
<p><%= combined.source %></p
...
<% else %>
<% end %>
Thank you for your help!

Ruby - Is it possible to create two different loops in the same "view" file?

I'm currently learning Ruby on Rails thanks to a website named codecademy, and I'm learning how to display informations from a database's array stocked into a variable
The exercice's correction is as shown below :
<div class="main movie-show">
<div class="container">
<div class="movie">
<!-- Display the movie info here -->
<div class="info">
<%= image_tag #movie.image %>
<h3 class="movie-title"><%= #movie.title %></h3>
<p class="movie-release-year"><%= #movie.release_year %></p>
<p class="movie-plot"><%= #movie.plot %></p>
</div>
</div>
<h2>Cast</h2>
<% #actors.each do |actor| %>
<div class="actor">
<%= image_tag actor.image %>
<h3 class="actor-name"><%= actor.first_name %> <%= actor.last_name %></h3>
<p class="actor-bio"><%= actor.bio %></p>
</div>
<% end %>
</div>
</div>
You can see in the "movie" part that they directly take the variable to display the information needed, while they stock all the "actor" 's part in another |actor| variable
My question is the following, as I didn't find any satisfying answer online, is it possible to use two variables the same way in the same file ? Like using
<% #movies.each do |m| %>
and
<% #actors.each do |a| %>
Will it work anyway ? Will there be an error?
You can use as many number of instance variables as you want in your view provided that they are properly defined in your controller code.
If you have defined both #actors and #movies instance variables in your controller action, then you can access then them in corresponding view. Remember: I wrote, corresponding view.
There is other way as well. For example, if you have defined relation between your Movie model and your Actor model, and the relation states that a movie can have many actors. In that case, you only need to instantiate #movies in your controller, and then you can access actors in the following way:
<% #movies.each do |movie| %>
<% movie.actors.each do |actor| %>
<%# All other relevant code %>
<% end %>
<% end %>
In case, you don't know about relations, you can define them in following way:
class Movie < ActiveRecord::Base
has_many :actors
end
class Actor < ActiveRecord::Base
belongs_to :movie
# actors table should have a column named 'movie_id' for this to work
end

Rails: how to count number of users?

here is my models.
User
unit_id
Unit
block_id
Block
postalcode_id
Postalcode
neighbourhood_id
Neighbourhood
name
the relations is for all is top belongs to bottom
this is my current index.html.erb file, i wish to output the number of user in each neighbourhood.
<% provide(:title, 'Neighbourhoods') %>
<ul class="thumbnails">
<% #neighbourhoods.each do |neighbourhood| %>
<li class="span3">
<div class="thumbnail">
<div style="position:relative;">
<%= link_to "Join", '#', class: "btn-join" %>
<%= image_tag(neighbourhood.name+".jpg", alt: neighbourhood.name) %>
</div>
<h2 style="margin-bottom:0px"><%= neighbourhood.name.titleize %></h2>
<% neighbourhood.postalcodes.each do |postalcode| %>
<%= postalcode.blocks.map(&:block).join(", ") %>
<% end %>
<br>
<%= neighbourhood.streetname.titleize %>
</div>
</li>
<% end %>
</ul>
Thanks in advance.
Assuming a Neighborhood has_many Users:
<%= neighbourhood.users.size %>
Note that counting is a relatively slow option, so you can optionally cache the number of users for speed using counter_cache:
class User < ActiveRecord::Base
belongs_to :neighborhood, :counter_cache => true
end
Then in a migration:
add_column :neighborhoods, :users_count, :integer, :default => 0
Seems like an awfully deeply nested set of associations. You may want to take a second look at your models and see if you can 'trim them down' a little. Maybe something like just have a User and Unit model, then add block, postal code and neighbourhood to Unit where you could do Unit.block, and Unit.postal_code...ect.
That being said with your current configuration (assuming correct associations of has_many/belongs_to) you should be able to do something like:
Neighbourhood.postal_code.block.unit.users.count
Good luck!

Resources