Identify correct answer from <li> list? - ruby-on-rails

I have questions which have five choices of which one is TRUE for choices.is_correct.
I currently have an ERB loop displaying the question and possible answer choices, with choices randomize in an ordered list (<li>).
In a separate ERB loop, I need to display the correct answer in the form of it's respective <li> label (A,B,C,D or E).
I feel like this might be possible through some sort of local variable, but none of my tests are working so far. Should local variables work, or am I approaching from the wrong perspective?
My current ERB for the question / answer section:
<% #free_questions.each_with_index do |question, i| %>
<div class="row justify-content-center">
<div class="col-lg-10">
<% #a = ("a".."z").to_a %>
<h5>Question <%= i+1 %>: <%= question.name %></h5>
<p>
<ol type="A">
<% #free_choices.where(question: question.id).sort_by{rand}.each do |choice| %>
<li><%= choice.name %></li>
<% end %><br />
</ol>
</p>
<% #free_choices.where(question: question.id, correct: TRUE).each do |choice| %>
<div class="accordion" id="accordionExample">
<% if choice.question.context.present? or choice.question.image.attached? %>
<div class="card">
<div class="card-header" id="headingC<%= i+1 %>">
<h5 class="mb-0">
<button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseC<%= i+1 %>" aria-expanded="true" aria-controls="collapseC<%= i+1 %>">
CLICK FOR QUESTION CONTEXT
</button>
</h5>
</div>
<div id="collapseC<%= i+1 %>" class="collapse" aria-labelledby="headingC<%= i+1 %>" data-parent="#accordionExample">
<div class="card-body">
<p>
<% if choice.question.image.attached? %>
<img src="<%= url_for(choice.question.image) if choice.question.image.attached? %>" class="rounded float-center" alt="context image for this question">
<% end %>
<!--TODO: Add more useful image alts here-->
<%= simple_format(choice.question.context) %>
</p>
</div>
</div>
</div>
<% end %>
<div class="card">
<div class="card-header" id="headingA<%= i+1 %>">
<h5 class="mb-0">
<button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseA<%= i+1 %>" aria-expanded="true" aria-controls="collapseA<%= i+1 %>">
CLICK FOR ANSWER
</button>
</h5>
</div>
<div id="collapseA<%= i+1 %>" class="collapse" aria-labelledby="headingA<%= i+1 %>" data-parent="#accordionExample">
<div class="card-body">
<p>
Correct Answer: <b><%= choice.name %></b>
</p>
<p>
Explanation: <%= raw(choice.question.explanation) %>
</p>
</div>
</div>
</div>
</div>
<% end %>
<hr />
</div>
</div>
<% end %>
EDIT: Adding the models below
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

Here I am outlining quick fix
replace <% #a = ("a".."z").to_a %> with <% alpha_numbers = ("A".."Z").to_a %>. You are using <ol type="A"> which prints list in upper case latter not in small case.
Move above snippet outside #free_questions.each_with_index loop so that you don't end up initializing same array for each question in loop.
Replace #free_choices.where(question: question.id).sort_by{rand}.each do |choice| with question.choices.shuffle.each_with_index do |choice, index|. As per the model relationship, question.choices will give same result as #free_choices.where(question: question.id). shuffle is better way of doing sort_by{rand}.
In the Choice model, add attr_accessor :alpha_order. This will create accessor methods.
Above <li><%= choice.name %></li> line add <% choice.alpha_order = alpha_numbers[index] %>. This line sets current alphabetic order of choice in an instance variable.
Replace #free_choices.where(question: question.id, correct: TRUE).each do |choice| with question.choices.select { |choice| choice.is_correct }.each do. This will loop through only those choices for given question where is_correct is true.
If you want to get alphabetic number attached to choice, access it using choice.alpha_order which will give correct alpha order.
Hope this helps.

Related

How to change code of every nth iteration

I got the following code in an .erb document:
<% #blog.order("created_at DESC").each do |d| %>
<!-- Blog Card -->
<div class="col-12 mb-3 mb-sm-7">
<article class="row align-items-lg-center">
<div class="col-lg-8">
<%= image_tag d.image.to_s, class:"img-fluid rounded" %>
</div>
<div class="col-lg-4">
<div class="py-5 px-lg-3">
<span class="d-block mb-2">
<p class="small text-body font-weight-bold text-cap"><%= d.tag_list %></p>
</span>
<h2>
<%= link_to d.title, d, class:"text-inherit" %>
</h2>
<p><%= d.summary.truncate(100) %></p>
<%= link_to "read more", d %>
</div>
</div>
</article>
</div>
<!-- End Blog Card -->
<% end %>
I want the code to change every nth time so i have multiple "layouts" (not in the ruby sense) in my blog. for this i added an if clause with following code:
<% if d.id % 5 == 0 %>
Unfortunately that does not work very well since i want to weave in the layout alternative into the regular layout like this:
┌─────────┐
└─────────┘
┌──┐┌──┐┌─┐
└──┘└──┘└─┘
┌─────────┐
└─────────┘
┌──┐┌──┐┌─┐
└──┘└──┘└─┘
So one large article, next row with three small ones etc.
Edit:
The alternating layout looks like this:
<div class="order-lg-1 col-sm-6 col-lg-4 mb-3 mb-sm-7">
<!-- Blog -->
<article
class="card align-items-start flex-wrap flex-row h-380rem gradient-y-overlay-sm-dark bg-img-hero rounded-pseudo transition-3d-hover"
style="background-image: url('<%= d.image.to_s %>');">
<div class="card-header border-0 bg-transparent w-100">
<p class="small text-white font-weight-bold text-cap mr-2"><%= d.tag_list %></p>
</div>
<div class="card-footer border-0 bg-transparent mt-auto">
<%= link_to d do %>
<h3 class="text-white"><%= d.title %></h3>
<span class="text-white-70">Read more<i class="fas fa-angle-right fa-sm ml-1"></i></span>
<% end %>
</div>
</article>
<!-- End Blog -->
</div>
How do i implement such a layout?
SOLUTION
I managed to do what i wanted with a combination of .each_with_index and using partials. like this:
<% #blog.order("created_at DESC").each_with_index do |d, index| %>
<%= index % 4 == 0 ? render("blog/var1", d: d) : render("blog/var2", d: d) %>
<% end %>
You can do something like this:
<% #blog.order("created_at DESC").each_with_index do |d, index| %>
<!-- Blog Card -->
<div class="col-#{index % 4 == 0 ? '12' : '4'} mb-3 mb-sm-7">
<article class="row align-items-lg-center">
<div class="col-lg-8">
<%= image_tag d.image.to_s, class:"img-fluid rounded" %>
</div>
<div class="col-lg-4">
<div class="py-5 px-lg-3">
<span class="d-block mb-2">
<p class="small text-body font-weight-bold text-cap"><%= d.tag_list %></p>
</span>
<h2>
<%= link_to d.title, d, class:"text-inherit" %>
</h2>
<p><%= d.summary.truncate(100) %></p>
<%= link_to "read more", d %>
</div>
</div>
</article>
</div>
<!-- End Blog Card -->
<% end %>
It means, for every 0, 4, 8, 12 .... index it'll add class col-12, otherwise it'll add class col-4
EDIT:
Yes, it is possible to insert whole partials as code:
Lets say, you created two separate files for small cards and big cards.
_small_blog_card.html.erb and _big_blog_card.html.erb
<% #blog.order("created_at DESC").each_with_index do |d, index| %>
<% if index % 4 == 0 %>
<%= render partial: 'big_blog_card', locals: {pass your data} %>
<% else %>
<%= render partial: 'small_blog_card', locals: {pass your data} %>
<% end %>
<% end %>

How to iterate over ActiveRecord model objects with a particular value of an attribute?

I am going to try to be very explicit because I've been trying to do a "special" iteration for several days.
I created cards which are named hiragana and are defined by a Letter (A, E, I, O, U) and decline in (KA, SA, TA... KE, SE, TE... (I, O, U => similar)).
I do an iteration with .each with hiragana instance to list them on the index page:
<% #hiraganas.each do |hiragana| %>
<li>
<%= render 'allhiraganas', hiragana: hiragana %>
</li>
<% end %>
The view is
<div class="row">
<ul class="list-inline text-center card-frame">
<li>
<div class="card">
<div class="front">
<% if current_user.try(:admin?) %>
<%= link_to hiragana_path(hiragana), class:'trash-hiragana', data: { confirm: 'Are you sure?' }, method: :delete do %>
<%= image_tag("delete-btn.png") %>
<% end %>
<% end %>
<span class="card-question popover-word" data-content="<h4 class='text-center letter-uppercase'>**<%= hiragana.bigletter.upcase %>**</h4><p class='text-center'><b><%= hiragana.midletter %></b> comme dans <b><%= hiragana.transcription %></b></p>">
<i class="fa fa-eye fa-lg"></i>
</span>
<!-- son de l'hiragana -->
<span class="audioclick popover-word" data-content="<p class='text-center'><b>le son arrive prochainement !</b></p>">
<i class="fa fa-volume-up fa-lg"></i>
</span>
<!-- image mnémotechnique -->
<% if hiragana.upload.blank? %>
<div class="idea">
<i class="fa fa-lightbulb-o fa-lg"></i>
</div>
<% else %>
<div class="idea">
<span class="popover-trigger"
data-toggle="popover"
data-content='<%= cl_image_tag(hiragana.upload,
:width => 210, :height => 290) %>'>
<i class="fa fa-lightbulb-o fa-lg"></i>
</span>
</div>
<% end %>
<!-- <div class="prononciation">
<i class="fa fa-comment"></i>
</div> -->
<div class="card-hiragana hiragana-<%=hiragana.bigletter.downcase.last%>">
<h1><b><%= hiragana.ideo1 %></b></h1>
</div>
<div class="card-katakana">
<p><%= hiragana.ideo2 %></p>
</div>
<div id="favorite_<%=hiragana.id%>">
<%= render 'favs/favorites', hiragana: hiragana %>
</div>
</div>
<div class="back">
<div class="col-sm-3 col-xs-4 col-md-3 containerbackcards-<%=hiragana.bigletter.downcase.last%>">
<div class="backcard-hiragana">
<h1><b><%= hiragana.ideo1 %></b></h1>
</div>
<div class="card-bigletter">
<h4><%= hiragana.bigletter.upcase %></h4>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
I want to iterate on the hiragana.bigletter method.
<span class="card-question popover-word" data-content="<h4 class='text-center letter-uppercase'>**<%= hiragana.bigletter.upcase %>**</h4><p class='text-center'><b><%= hiragana.midletter %></b> comme dans <b><%= hiragana.transcription %></b></p>">
<i class="fa fa-eye fa-lg"></i>
</span>
because I want to have all hiraganas with the bigletter A display on a vertical column, all hiraganas with the bigletter E display on another vertical column and so on.
Some people told me about .select but I don't know where to put it. In the hiragana model?`
Please could you guide me what can I do to dry my code in model. Here is the hiragana model:
class Hiragana < ActiveRecord::Base
belongs_to :user
has_many :favs, dependent: :destroy
mount_uploader :upload, ImageUploader
mount_uploader :sound, SoundUploader
def is_faved_by(user)
self.favs.where(user: user).take
end
end
Thank you for your help.
I think this is what you want:
<% #hiraganas.select { |hiragana| hiragana.bigletter == 'a' }.each do |hiragana| %>
<%= render 'somehiraganas', hiragana: hiragana %>
<% end %>
It's preferable to minimize code in templates, so it would be better to add a method to the model
class Hiragana < ActiveRecord::Base
def self.with_bigletter(bigletter)
where(bigletter: bigletter).order(:midletter)
end
end
and assign the result of Hiragana.with_bigletter('a') and so on to a template variable or variables in your controller.
It might be better for performance to query all Hiraganas with ActiveRecord and have with_bigletter do select as in my first answer, but I wouldn't worry about that unless you actually had a performance problem.

How to filter results by clicking on checkbox in ruby on rails

I am a newbie in ruby on rails it's also my first ruby application.
I want to filter results by clicking on checkbox which is coming from
the database and showing on the right side of my webpage, the checkbox
is lying on the left side. In the below I attached my webpage's
screenshot for easy understanding.
Anyone can help me, please, how can I solve this issue?
My Controller file code:resumes_controller.rb
class ResumesController < ApplicationController
before_filter :recruiter!
def resumes
#resume = Jobseeker.paginate(page: params[:page], :per_page => 10).order('jobseeker_id DESC')
end
end
My view file code: resumes.html.erb
<%= form_for :jobseekers,url: resumes_path(#jobseekers), action: :update, method: :post do |f| %>
<div>
<label for="Title">Education</label>
<div class="checkbox">
<%= check_box("tag", {checked: true}) %>Masters
</div>
<div class="checkbox">
<%= check_box("tag", {checked: true}) %>Bachelor
</div>
<div class="checkbox">
<%= check_box("tag", {checked: true}) %>Associates
</div>
<div class="checkbox">
<%= check_box("tag", {checked: true}) %>Diploma
</div>
More
</div>
<% end %>
<!-- item1 -->
<% #resume.each do | res| %>
<div class="job-item bio-card">
<div class="employer-information">
<div class="col-sm-6">
<ul class="list-unstyled">
<li class="employ-name">
<a href="<%= view_profile_path(:jobseeker_id => res.jobseeker_id) %>">
<%= res.first_name %> <%= res.last_name %></a> <span>- <%= res.current_address %></span>
</li>
<li><%= res.institute_name %></li>
</ul>
</div>
<% if res.attach_resume.nil? %>
<div class="col-sm-6 employ-pdf-box">
<div class="employ-pdf">
<i class="fa fa-file-powerpoint-o icon"></i>
<h3>Empty</h3>
</div>
</div>
<% else %>
<div class="col-sm-6 employ-pdf-box">
<a href="<%= res.attach_resume.resume %>"target="_blank">
<div class="employ-pdf">
<i class="fa fa-file-powerpoint-o icon"></i>
<h3><%= res.first_name %> <%= res.last_name %>.pdf</h3>
</div>
</a>
</div>
<% end %>
</div>
</div>
<% end %>
<!-- End item1 -->

How to put content under the first record rails 4

I am on Rails 4. I have two resources: subarticles and articles. Subarticles are nested in articles like so:
resources :articles do
resources :subarticles do
member do
put "like" => "subarticles#upvote"
put "dislike" => "subarticles#downvote"
end
end
end
On the articles show page, I display all of the subarticles. However, I would like to place some of the article attributes ( specifically pictures and videos) directly under the first subarticle.
I am having trouble finding any documentation on doing so.
Also note that I have subarticles ordered by number of votes. So if one gets voted higher than the other, it will go to the top. But I want to keep the same pictures and videos right under the first subarticle.
Here is a simplified version of my Article show page:
<div class="row">
<div class="col-md-9">
<div class="well" style="background:white; height:230px">
<%= #article.title.titleize %><br>
<%= social_share_button_tag %>
</div>
<% #subarticles.each do |subarticle| %>
<div class="well" style="background:white">
<%= subarticle.rating %><br>
<%= subarticle.whyrating %><br>
<div class="row" style="margin-top:40px;">
<div class="col-md-7 col-md-offset-1" style="margin-top:30px">
<%= link_to like_article_subarticle_path(#article, subarticle), class: "like", method: :put do %>
<button type="button" class="btn btn-success btn-lg" aria-label="Left Align" style="margin-right:5px">
<span class="glyphicon glyphicon-thumbs-up" aria-hidden="true"></span> Helpful
</button><span class="badge" style="margin-right:10px"><%= subarticle.get_upvotes.size %></span>
<% end %>
<%= link_to dislike_article_subarticle_path(#article, subarticle), class: "like", method: :put do %>
<button type="button" class="btn btn-danger btn-lg" aria-label="Left Align" style="margin-right:5px">
<span class="glyphicon glyphicon-thumbs-down" aria-hidden="true"></span> Unhelpful
</button><span class="badge"><%= subarticle.get_downvotes.size %></span>
<% end %>
</div>
</div>
</div>
<% end %>
<div class="well" style="background:white; text-align:center">
<h4>Pictures & Videos</h4><br>
<%= image_tag #article.image1(:medium) %><br>
<div class="embed-responsive embed-responsive-4by3">
<iframe class="embed-responsive-item" src="<%= #article.video1 %>"></iframe>
</div>
</div>
</div>
</div>
Because of the #subarticles.each do it will push pictures and videos all the way to the bottom. What is the best way to show just the first subarticle, then pictures & videos, then the rest of the subarticles?
Let me know if I need to show any other code.
<% #subarticles.each_with_index do |subarticle, i| %>
<div class="well" style="background:white">
....... // subarticle contents
</div>
<% if i==0 %>
// put articles content here
<% end %>
<% end %>
In that way after the first subarticle the if condition checks the loop index, as the loop index is currently 0, then it will first show the subarticle first content, then for index 0 it shows the article contents.
You can always use a flag for that:
<% first_one = false %>
<% #subarticles.each do |subarticle| %>
<div class="well" style="background:white">
...
</div>
<% unless first_one %>
// article contents here....
<% first_one = true %>
<% end %>
<% end %>

How do I detect the first iteration within my view? (Rails 4)

In my view I have:
<div class="item active">
<%= image_tag "2.jpg",size: "500x300", class: "no-resize" %>
<div class="carousel-caption">
Some tag.
</div>
</div>
<% #photos.each do |photo|%>
<div class="item">
<%= image_tag photo.attachment.url,size: "500x300",class: "no-resize" %>
<div class="carousel-caption">
Some tag.
</div>
</div>
<% end %>
Is there DRYer way of accomplishing this (as the only change I make is adding the class 'active' for the first photo) i.e. can I put the first item within the loop and detect the first iteration?
Try each_with_index
<% #photos.each_with_index do |photo, i |%>
<div class="item <%= "active" if i.zero? %>">
<%= image_tag photo.attachment.url,size: "500x300",class: "no-resize" %>
<div class="carousel-caption">
Some tag.
</div>
</div>
<% end %>
['apple', 'orange', 'pear'].each_with_index do |fruit, index|
p "first is #{fruit}" if index == 0
p fruit
end

Resources