RAILS - HOW TO ADD VOTES IN A POLL - ruby-on-rails

I'm new to Rails and I'm using translate to post here.
I'm practicing rails and for that I set up a poll (voting) system.
Until then the voting is working normally, the votes are stored correctly, however, I would like to set up a screen on the frontend to display the result, and that's where I'm having difficulty.
How can I sum the votes from the PollOptions table of the "Votes" column. I would like to display it like this:
name: 10 votes or X% of votes
name: 10 votes or X% of votes
name: 10 votes or X% of votes
As I understand it, I need to create a method in the controller that will do this sum?
Any documentation links/tips, I'd appreciate it.
polls_controller
class PollsController < ApplicationController
def index
#poll = Poll.where(finished_at: nil).last
#poll_options = #poll.poll_options.order :name
end
def vote
#poll_option = PollOption.find params[:poll_option_id]
#poll_option.increment! :votes
respond_to do |format|
format.turbo_stream { render :vote }
end
end
end
model:
poll
class Poll < ApplicationRecord
has_many :poll_options
end
poll_option
class PollOption < ApplicationRecord
belongs_to :poll
end
In this view, I would like to call the result of the vote.
view _poll.html.erb
<div id="poll-container" class="col-lg-8 mx-lg-auto">
<div class="card shadow">
<div class="card-header">
<h2 class="card-title text-center">
<%= #poll.name %>
<p>
<%= #poll_options.pluck(:name).to_sentence(last_word_connector: ' ou ') %>
</h2>
</div>
<div class="card-body">
<div class="d-flex flex-column bd-highlight mb-3">
<% #poll_options.each do |item| %>
<p>
<%= button_to vote_url,
method: :post,
class: "btn btn-outline-secondary",
params: { poll_option_id: item.id } do %>
<h2>
<%= item.name %>
<%= image_tag item.photo, size: "40x40" %>
</h2>
<% end %>
<% end %>
</div>
</div>
</div>
</div>
https://i.stack.imgur.com/JQfQP.png
Thanks in advance for any guidance.

You can use ActiveRecord::Calculations sum (.sum(:votes)) to sum all the rows for the votes column under poll_options.
To find all the votes of a poll you need the following
#poll.poll_options.sum(:votes)
Then to create the % for the PHP for example you could do
total_votes = #poll.poll_options.sum(:votes)
php_votes = #poll.poll_options.where(name: 'PHP').votes
(php_votes / total_votes).to_i * 100

Related

Rails - def search issue

OK, I'm very new to Rails, so please be patient :)
I'm not sure how to structure the def search in the page controller so that it returns back the correct results (right now the results are blank).
I'm adapting a course code to my project. The original course is showing how to search for room by address rather than through the drop down attribute selection. It was also ordering the results by distance rather than a price. Here is what I come up with for my project:
def search
# STEP 1
if params[:search].present? && params[:search].strip != ""
session[:loc_search] = params[:search]
end
# STEP 2
if session[:loc_search] && session[:loc_search] != ""
#rooms_type = Room.where(active: true).order(session[:loc_search], order: 'price')
else
#rooms_type = Room.where(active: true).all
end
# STEP 3
#search = #rooms_type.ransack(params[:q])
#rooms = #search.result
#arrRooms = #rooms.to_a
end
I'm pretty sure that there are several mistakes in the def search.. could someone help me to figure this out?
Here are my Room model attribute.
class CreateRooms < ActiveRecord
def change
create_table :rooms do |t|
t.string :type
t.timestamps
end
end
end
Search widget on the homepage is structured in the following way:
<%= form_tag search_path, method: :get do %>
<div class="row">
<div class="col-md-7">
<%= select_tag :type, options_for_select([['Single', 1], ['Double', 2]]), ,class: "form-control" %>
</div>
<div class="col-md-2">
<%= submit_tag "Search", class: "btn btn-normal btn-block" %>
</div>
</div>
<% end %>
The search page does the following:
<div class = "row">
<% #rooms.each do |room| %>
<div class = "col-md-4">
<div class = "panel panel-default">
<div class = "panel-heading preview">
<% image_tag room.cover_photo (:medium) %>
</div>
<div class = "panel-body">
<% link_to room.type, room %>
</div>
</div>
</div>
<% end %>
</div>
Thank you.
UPDATED code based on #crispychicken feedback - see the screenshots enter image description here
First Issue: The content of your model is wrong. It belongs into a migration. Also, the active and price attributes are missing. And I think the attribute type is protected. You should rename it to something like RoomType.
To create the migration:
rails g migration create_rooms room_type:string active:boolean price:integer
And then do rails db:migrate
Second Issue:
In your controller, change the code in your Step 2 to:
#rooms_type = Room.where(active: true, room_type: session[:loc_search]).order(:price)
And you have to change type to room_type everywhere in your files.

How to correctly call models in controller

My Chefs Model is linked to my Meals Model through chef_id. I am displaying information about the chef, and would also like to show information about his meals. I have not been able to figure out the correct way to call it in the controller. Any ideas?
chef controller:
def index
#chefs=Chef.paginate(page: params[:page])
#meals = ????? Cant figure out how to call this
end
Index.html.erb
<div class = 'chef'>
<div class = 'row'>
<% #chefs.each do |chef| %>
<%= render chef %>
<% end %>
</div>
</div>
<%= will_paginate %>
_chef partial
<div class = 'span4'>
<div class = 'chef-box'>
<h2><center><%= link_to chef.name, chef %></center></h2>
<h2><center>"<%= chef.description %>"</center></h2>
<h2><center><%= THIS IS WHERE I WANT TO DISPLAY INFORMATION ON MEALS %></center></h2>
</div>
</div>
If you just want to access the #meals, than you can get it just by for an instance of #chef:
#meals = #chef.meals
given that you have defined the association in the Chef class like following:
class Chef < ActiveRecord::Base
has_many :meals
#rest of the code
end
Have a look at Active Record Associations here.
So, Here I am just giving an example of how to use it in views, you may have to correct it:
in _chef partial
<div class = 'span4'>
<div class = 'chef-box'>
<h2><center><%= link_to chef.name, chef %></center></h2>
<h2><center>"<%= chef.description %>"</center></h2>
<% chef.meals.each do |meal| %>
<h2><center><%= meal.information %></center></h2>
<% end %>
</div>
</div>
You will need to call correct attribute of meal in above sample code.
As previously mentioned – first and foremost make sure the relation is set up in your chef model:
class Chef < ActiveRecord::Base
has_many :meals
end
Then you can call any Chef.meals, whether that's in your controller as:
def index
#chef = Chef.paginate(page: params[:page])
#meals = #chef.meals
end
Or just in your view:
<div class = 'span4'>
<div class = 'chef-box'>
<h2><center><%= link_to chef.name, chef %></center></h2>
<h2><center>"<%= chef.description %>"</center></h2>
<h2>Has <%= pluralize(chef.meals.size, 'meal') %></h2>
<% chef.meals.each do |meal| %>
<% meal.name %>
<% end %>
</div>
</div>
Of note – since Chef is a model name, you should be able to render your _chef.html.erb more cleanly with simply:
<div class = 'chef'>
<div class = 'row'>
<%= render #chef %>
</div>
</div>
<%= will_paginate %>
Note that #chef is singular to match your controller, you could also pass it a collection <%= render #chefs %> if that's what's set up in your controller, and it will do render each chef separately.

Paginating Tags in Rails 4

I'm using Kaminari to paginate my posts page. A post has many tags and each tag links to a "Show" page that displays all posts with that tag. I'm trying to paginate this tags page but it never quite works.
tags/show
<div class="post-index">
<h1><%= #tag.name %></h1>
<ul>
<% #tag.posts.each do |post| %>
<li>
<div class="post">
<div class="featured-image">
<%= link_to image_tag(post.featured_image.url(:featured)), post_path(post) %>
</div>
<div class="info">
<div class="title">
<h2><%= link_to post.title, post_path(post) %></h2>
</div>
<div class="excerpt">
<p><%= truncate(strip_tags(post.body), length: 360) %></p>
</div>
</div>
</div>
</li>
<% end %>
</ul>
<%= paginate #tags %>
</div>
tag.rb
lass Tag < ActiveRecord::Base
has_many :taggings
has_many :posts, through: :taggings
paginates_per 2
end
tags_controller.rb
class TagsController < ApplicationController
def show
#tag = Tag.find(params[:id]).page(params[:page])
end
end
I've tried all I can think of. The examples Kaminari uses are
tag = Tag.order(:name).page(params[:page])
but this doesn't work and returns a no method "posts" error. I tried paginating the posts model instead but that doesn't work.
If I remove any pagination reference, it displays all the posts correctly on the tag page.
Thanks for any advice
I'm not sure about what do you want to paginate? Tags or posts? In your code, you want to paginate "#tags", but you never define "#tags".
#tag = Tag.find(params[:id])
#posts = #tag.posts.page(params[:page])

how to render this partial in rails

i am trying to render this partial of the association belongs_to and has_many i.e
my model is as thus
activity Model
class Activity < ActiveRecord::Base
has_many :talks
end
talk model
class Talk < ActiveRecord::Base
belongs :activity
end
in my talk controller i have
#activities = Activity.where(user_id: [current_user.friend_ids, current_user])
#talks = Talk.find(:all, :order => "created_at DESC")
and in view i have
<% activity.talks.each do |c| %>
<div class="media">
<a class="pull-left" href="#">
<%= image_tag(c.user.image.url(:tiny),:style=> "width: 100%;")%>
</a>
<div class="media-body">
<strong><%= c.user.username %></strong> <%= c.details %><br>
<small><span class="muted"><%="#{time_ago_in_words(c.created_at)} ago "%></span></small>
</div>
</div>
<% end %>
this displays all the talk for each activity
how do i create a partial of <% activity.talks.each do |c| %>
Create a partial in
app/views/talks/_talk.html.erb
and call
<%= render activity.talks %>
This will render one _talk.html.erb partial for each talk in the activity.talks collection, which will have access to a talk variable.
Furthermore, you can optimize the code by preventing N + 1 queries. In your controller,
#activities = Activity.includes(:talks).where(user_id: [current_user.friend_ids, current_user])
Notice the includes(:talks). Read more about eager loading in the docs linked above.

Submitting form info to Model from view, then invoking the model to run

I am trying to submit info from a form in my view, that passes the submitted info :hashtag into the model and then runs the model with that info. But it seems thats my model just runs with the words "hashtag" instead of the form info. I believe it is close. I just can't figure out where to go next.
home.html.erb
<div class="row">
<div class="span6 offset2">
<%= form_for :hashtag do |f| %>
<div class="input-prepend input-append">
<span class="add-on swag">#</span>
<%= f.text_field :hashtag , class: "span3 inverse", id:"appendedPrependedInput" %>
<%= f.submit "Swag!", class: "btn btn-inverse" %>
<% end %>
</div>
</div>
<div class="span4">
<div id="hashtags">
<% #random_hashtags.each do |hashtag| %>
<blockquote><%= hashtag.content %></blockquote>
<div class="from">— #<%= hashtag.screen_name %></div>
<% end %>
</div>
</div>
</div>
hashtag.rb
class Hashtag < ActiveRecord::Base
attr_accessible :content, :profile_image, :screen_name, :tweet_date, :tweet_id
def self.pull_hashtag
Twitter.search("%#{hashtag}").results.map do |tweet|
unless exists?(tweet_id: tweet.id)
create!(
tweet_id: tweet.id,
content: tweet.text,
profile_image: tweet.profile_image_url,
screen_name: tweet.from_user,
tweet_date: tweet.created_at
)
end
end
end
end
hashtags_controller
class HashtagsController < ApplicationController
def home
#random_hashtags = Hashtag.order("RANDOM()").limit(4)
end
def create
#hashtag = Hashtag.pull_hashtag(params[:search])
end
end
Updated code that I am currently using now as I was not posting anything to the model
It is going though on submit but it seems nothing from there.
Update 2,
I am trying to post the information to the database, by taking the info from the form, running a Twitter.search on it and creating the results in my database.
Can you try to replace with this?
form_for #hashtag, :url => :action => 'home'
my guess is that the action needs to be specified.

Resources