刘华佼的全栈学习记录

如何添加点赞功能

| Comments

之前从论坛看了很多教程,受益匪浅,但自己没有什么东西分享,一直很遗憾。这次终于自己参考rails101教程,死磕出一个点赞功能了,特来分享给大家。

这次能做出这个功能,要感谢助教zhengzhi、marcfly、lucas、milesmao、Nic、jacksparrow、leichaofan同学的帮助和启发。

好,言归正传。点赞功能关键点就是多对多的关系,要能够记下谁(user)给哪个工作(job)点了赞。

教材中的多对多关系有,第二课的post,第三课的“加入社团”功能,招聘网站的resume。

我主要参照了这三个model的写法,加入社团、退出社团的写法,以及招聘网站第八部分解答中,显示resume总数的方法。按钮的class参照了招聘教材中publish、hidden的写法。

最终效果图

jobs#show页面
点赞前:

点赞后:

jobs#index效果图:

步骤一:构思model

点赞功能,要同时与用户和工作相关, 要记录哪个用户给哪个工作投过票,所以新建的model有两个栏位:

job_id ( integer )
user_id ( integer)

先新建vote model:

rails g model vote job_id:integer user_id:integer
rake db:migrate

步骤二:设定User和Vote的关系

app/models/user.rb里设定:

has_many :votes
has_many :voted_jobs, :through => :votes, :source => :job

app/models/vote.rb里设定:

class Vote < ApplicationRecord
  belongs_to :job
  belongs_to :user
end

步骤三:设定Job和Use通过Vote建立的关系

app/models/job.rb

  has_many :votes
  has_many :voters, through: :votes, source: :user

步骤四:Terminal中输入rails c测试:

 u = User.first
 j = Job.first
 j.voters << u
 j.votes
 u.voted_jobs

只要正常显示没有报错,应该对了。输入exit退出。

步骤五:判断是否给该工作点过赞

app/models/user.rb

  def is_voter_of?(job)
    voted_jobs.include?(job)
  end

然后“重开”rails console:
输入

u = User.first
j = Job.first
u.is_voter_of?(j)

最后输出true就对了。输入exit退出。

步骤六:修改jobs/show.html.erb

app/views/jobs/show.html.erb加入:

<span class="pull-left">
  <% if current_user && current_user.is_voter_of?(@job) %>
    <%= link_to("", downvote_job_path(@job), method: :post, class: "fa fa-heart fa-2x", style: "color:red;") %>
   <% else %>
    <%= link_to("", upvote_job_path(@job), method: :post, class: "fa fa-heart-o fa-2x") %>
  <% end %>
</span>

步骤七:实作model层的upvote和downvote

app/models/user.rb 里加入:

  def upvote!(job)
    voted_jobs << job
  end

  def downvote!(job)
    voted_jobs.delete(job)
  end

步骤七:在jobs_controller里实作upvote和downvote 的action

app/controllers/jobs_controller.rb

  def upvote
   @job = Job.find(params[:id])

    if !current_user.is_voter_of?(@job)
      current_user.upvote!(@job)
    end

    redirect_to :back
  end

  def downvote
    @job = Job.find(params[:id])

    if current_user.is_voter_of?(@job)
      current_user.downvote!(@job)
    end
    redirect_to :back
  end

在jobs_controller里的before_action里加:downvote, :upvote:

before_action :authenticate_user!, only: [:new, :create, :update, :edit, :destroy, :downvote, :upvote]

步骤八:

config/routes.rb

  resources :jobs do
    member do()
      post :upvote
     post :downvote
    end

步骤九:

如果想要显示总赞数,在步骤六的代码最上面加上一句:

<%= @job.voters.count %>

如果要在http://localhost:3000/jobs/ 里也显示点赞栏,加上代码:

      <td>招聘职位</td>
      <td>收藏</td>
      <td>点赞</td>
...
<td><%= link_to(job.title, job_path(job)) %></td>
<td>
  <% if current_user && current_user.is_member_of?(job) %>
        <%= link_to("", outbox_job_path(job), method: :post, class: "fa fa-folder") %>
  <% else %>
        <%= link_to("", inbox_job_path(job), method: :post, class: "fa fa-folder-o") %>
  <% end %>
</td>
<td>
  <%= job.voters.count %>
  <% if current_user && current_user.is_voter_of?(job) %>
    <%= link_to("", downvote_job_path(job), method: :post, class: "fa fa-heart", style: "color:red;") %>
  <% else %>
    <%= link_to("", upvote_job_path(job), method: :post, class: "fa fa-heart-o") %>
  <% end %>
</td>

如果觉得不够明白,可以去看我的作品的源代码,分支step9。特别欢迎投票支持后再看源代码!

免费用户如果想购买VIP课程,可以使用我的专属推荐码减学费哦:6194-e895-58cb

如果对本教程有疑问,欢迎提出来讨论!

参考资源:

雷超凡写的做一个漂亮的收藏功能
戴建林写的简单六步实现对产品点赞功能
招聘网站教材的12-2(解答)招聘网站第八部分
rails101教材的7-使用者应该要“加入社团”才能发表文章

Comments

comments powered by Disqus