<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: James Chou</title>
    <description>The latest articles on DEV Community by James Chou (@jameschou93).</description>
    <link>https://dev.to/jameschou93</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F41122%2F8356106c-c87d-46eb-90a4-d5e77579a375.jpeg</url>
      <title>DEV Community: James Chou</title>
      <link>https://dev.to/jameschou93</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jameschou93"/>
    <language>en</language>
    <item>
      <title>Vote on Rails[Bonus: Vote as a guest!]</title>
      <dc:creator>James Chou</dc:creator>
      <pubDate>Sat, 18 Nov 2017 20:33:08 +0000</pubDate>
      <link>https://dev.to/jameschou93/vote-on-railsbonus-vote-as-a-guest-ckf</link>
      <guid>https://dev.to/jameschou93/vote-on-railsbonus-vote-as-a-guest-ckf</guid>
      <description>

&lt;p&gt;As a fellow Rails developer, you have most likely received the task of creating something similar to a blogging app (bare with me if you haven't). Recently, I have had to create one complete with commenting, sharing, and voting capabilities. Typically I would take time to map out the schema prior to running &lt;code&gt;rails new&lt;/code&gt; but in this case I was pressed for time. Luckily I had the &lt;a href="https://github.com/ryanto/acts_as_votable"&gt;&lt;code&gt;act_as_voteable&lt;/code&gt; gem&lt;/a&gt; to save the day!&lt;/p&gt;

&lt;p&gt;Installation is very basic as all you need to do is include the gem in your gemfile and bundle:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'acts_as_votable'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'~&amp;gt; 0.11.1'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;and generate + migrate their migration:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails generate acts_as_votable:migration
rake db:migrate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now let's roll!&lt;/p&gt;

&lt;p&gt;My favorite thing about this gem is that the methods to create votes and show votes are simple. First thing we need to do is make the associations between the objects you want to vote on and the voters. In this case, I want to users to vote on my posts. Here is a look at my User.rb and Post.rb files:&lt;/p&gt;

&lt;p&gt;user.rb&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="c1"&gt;# Voter.&lt;/span&gt;
  &lt;span class="n"&gt;acts_as_voter&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;post.rb&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="c1"&gt;#Votee&lt;/span&gt;
  &lt;span class="n"&gt;act_as_votable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now that the app knows that users vote on posts, we need to create upvote and downvote methods in our Post controller. The awesome thing is that the gem already limits one vote per user(default but can allow duplicates) and you can also make vote weighted based on user role if you wanted! I did not use weighted votes in my app but if you want learn more about how else you can play around with voting, definitely look at the great documentation that &lt;a href="https://github.com/ryanto/acts_as_votable"&gt;ryanto has for his gem!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Post Controller&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;upvote&lt;/span&gt;
    &lt;span class="vi"&gt;@post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="vi"&gt;@post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;liked_by&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;
    &lt;span class="c1"&gt;#can change current_user to any other voter&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;downvote&lt;/span&gt;
    &lt;span class="vi"&gt;@post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="vi"&gt;@post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disliked_by&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;
    &lt;span class="c1"&gt;#can change current_user to any other voter&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;and in my html view:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to "Like", like_post_path(@post, method: :put) %&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What you have read so far is a barebones quick install tutorial and there is definitely potential for further manipulation of votes. &lt;a href="https://github.com/ryanto/acts_as_votable"&gt;See Documentation!&lt;/a&gt;. But I did find myself in an issue...what if I want guests to vote?!&lt;/p&gt;

&lt;p&gt;Through extensive research from various sources(google,stackoverflow,my sensai, etc) I found a way to do this with session ids!&lt;/p&gt;

&lt;p&gt;This time, we have to allow users AND sessions to act as voters; we need to add &lt;code&gt;act_as_voter&lt;/code&gt; in both of the votersession.rb and user.rb files. But first we need to generate a votersession model.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;rails&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;migration&lt;/span&gt; &lt;span class="n"&gt;votersessions&lt;/span&gt; &lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="ss"&gt;:string&lt;/span&gt;
&lt;span class="n"&gt;rails&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="ss"&gt;:migrate&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;and now we simple need to change our controller to use the User object to vote and, if not available, the session id instead. Here's my moist(not &lt;a href="http://wiki.c2.com/?DontRepeatYourself"&gt;DRY&lt;/a&gt;)&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;upvote&lt;/span&gt;
    &lt;span class="vi"&gt;@idea&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Idea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="c1"&gt;# vote as user if logged in&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;
      &lt;span class="vi"&gt;@idea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upvote_by&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;
    &lt;span class="c1"&gt;# else vote is associate with session&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="vi"&gt;@session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;VoterSession&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;session_id: &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;session_options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="c1"&gt;# Create new votersession if unique id does not exist&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@session&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
          &lt;span class="vi"&gt;@session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;VoterSession&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;session_id: &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;session_options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="vi"&gt;@idea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upvote_by&lt;/span&gt; &lt;span class="vi"&gt;@session&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Keep in mind, there is still a chance for voters to vote more than once, for example, if the user is not logged in, they can vote again each time they clear their cookies or use a different computer so I recommend this method for smaller apps that need a quick voting structure. &lt;/p&gt;

&lt;p&gt;My hope is that this post can be of use to a dev out there or at the very least sparked an idea. Drop a line if you have any questions!&lt;/p&gt;


</description>
      <category>rails</category>
      <category>actasvoteable</category>
      <category>posts</category>
      <category>gem</category>
    </item>
  </channel>
</rss>
