【Ruby on Rails全栈课程】3.10 网站主页面显示帖子列表

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shine_a/article/details/87355932
1、完善样式,编辑app/assets/stylesheets/home.css.scss文件,在原先代码后面添加下面代码
.issue-list {
  background: #fff;
  clear: both;
  padding: 0 1em;
  margin-bottom: 1em;
  border: 1px solid #ddd;
  article {
    border-bottom: 1px solid #e3e3e3;
    position: relative;
    margin-top: 0;
    padding: 1em 0;
    .body {
      margin-right: 2em;
      width: 72%;
      float: left;
      .read-more{
        background-color: #f5999d;
        color: #fff;
        font-size: 14px;
        border-radius: 4px;
        letter-spacing: -0.3px;
        display: inline-block;
        line-height: 1.7;
        font-weight: 100;
        padding: 0 5px;
        margin-top: 2px;
      }
      .meta-data {
        color: #999;
        font-size: 12px;
      }
      h5 {
        font-size: 22px;
        line-height: 35px;
        font-weight: normal;
        margin: 0 0 5px;
        a {
          color: #555;
          &:hover {
            color: black;
          }
        }
      }
      .icon-top {
        background-color: #0054a5;
        color: #fff;
        font-size: 12px;
        border-radius: 4px;
        letter-spacing: -0.2px;
        display: inline-block;
        line-height: 1.6;
        font-weight: 100;
        padding: 0 6px;
        float:left;
        margin-top: 7px;
        margin-right: 5px;
      }
      .icon-good {
        background-color: #f16522;
        color: #fff;
        font-size: 12px;
        border-radius: 4px;
        letter-spacing: -0.2px;
        display: inline-block;
        line-height: 1.6;
        font-weight: 100;
        padding: 0 6px;
        float:left;
        margin-top: 7px;
        margin-right: 5px;
      }
      .as_sb {
        display: block;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
    }
    .issue-comment-count {
      float: right;
      margin-top: 15px;
      a {
        font-size: 45px;
      }
    }
    .avatar {
      width: 85px;
      border:1px solid #a5b6c8;
      background:#eef3f7;
      text-align: center;
    }
  }
}
2、添加Font Awesome 矢量图标库,为后面调用点赞、评论图标做准备。

在views/layouts/application.html.erb中添加一行代码,加上之后就可以直接取用图标库里面的图标了

<!--参考代码,无需粘贴-->
<!--<%= javascript_include_tag "application","vendor/jquery.anystretch.min", 'data-turbolinks-track': 'reload'%>-->
<link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.css">
3、编辑home_controller.rb的index方法

我们在网站首页上显示目前已创建帖子的列表,需要编辑home_controller.rb文件中的index方法,查出符合条件的帖子对象集合,赋值到实例变量@posts中,然后在views/home/index.html.erb文件中遍历@posts对象集合,来显示这些帖子

def index
  @posts = Post.where(status:0).order(as_type: :desc,updated_at: :desc)
end

代码解析:

  • @posts = Post.where(status:0).order(as_type: :desc,updated_at: :desc)
    其中order(as_type: :desc,updated_at: :desc)是先按照as_type倒序排序,再按照updated_at倒序排序。意思是帖子的顺序是置顶帖—>精华帖—>普通帖。同一类型的帖子再按帖子的修改时间排序。
4、编辑views/home/index.html.erb文件,在原先代码的后面添加下列代码:
<div class="container clearfix">
  <div class="issue-list">
    <% @posts.each do |p| %>
      <article class="issue clearfix">
        <div class="avatar body">
          <!-- 获取发帖用户的名字,get_account_name是在post.rb文件中定义的实例方法 -->
          <a class="read-more" href="#"><%= p.get_account_name %></a>
          <!-- 获取发帖的时间 -->
          <p class="time"><%= p.get_updated_at %></p>
        </div>
        <div class="body">
        <% if p.as_type == 2 %>
          <div class="icon-top" title="置顶">置顶</div>
        <% elsif p.as_type == 1 %>
          <div class="icon-good" title=""></div>
        <% end %>
        <h5 class="title">
          <%= link_to "#{p.head}", "#" %>
        </h5>
        <a class="as_sb" href="#"><%= p.body %></a>
        </div>
        <div class="issue-comment-count">
          <a data-remote="true"><i class="fa fa-comment-o" style="padding-right: 15px;">
          <!-- 获取评论数,方法还没完善,先设为1 -->
          <%= "#{p.get_post_items}" %>
          </i></a>
          <!-- 先判断当前是否有用户登录,再判断用户是否为此帖子点过赞 -->
          <% if @current_user && p.get_thumb_info(@current_user.id) %>
            <a data-remote="true" href="#" id="reduce" class="fa fa-thumbs-up">
              <%= "#{p.get_thumbs}"%>
            </a>
          <%elsif @current_user%>
            <a data-remote="true" href="#" id="increase" class="fa fa-thumbs-o-up">
              <%= "#{p.get_thumbs}"%>
            </a>
          <!-- 没有账户登录时的情况 -->
          <% else %>
            <a data-remote="true" href="#" class="fa fa-thumbs-o-up" onclick="alert('您还未登录,请先登录')">
              <%= "#{p.get_thumbs}"%>
            </a>
          <% end %>
        </div>
      </article>
    <% end %>
  </div>
</div>

代码解析:

  • <% @posts.each do |p| %> <% end %>
    循环代码,将在home_controller.rb的index方法中查出的@posts对象集合进行遍历,显示出符合条件的帖子

  • <a class="read-more" href="#"><%= p.get_account_name %></a>
    其中嵌入的ruby代码<%= p.get_account_name %>,p代表@posts对象集合中当前遍历的Post实例对象,get_account_name是一个实例方法,我们还没有定义,用来获取发帖用户的用户名,后面我们会在app/models/post.rb文件中定义这个实例方法
    Post表中,存的是用户的account_id,我们想获得用户名,必须得先通过id查出Account对象,然后再获取对象的name字段。你可能会问,为什么不在views/home/index.html.erb文件直接查询出Account对象的name字段呢?也就是说<%= p.get_account_name %>替换成<%= Account.where(id:p.account_id).first.name %>
    当然这也是可行的,但是基于代码规范以及后期维护的原因,我们一般将对Post对象的操作统一写到模型文件(app/models/post.rb)里面,这样如果Post对象想在别的页面查询出相应客户的名称,就可以直接用Post对象调用get_account_name方法了。
    后面的p.get_updated_at(获取帖子更新时间)、p.get_post_items(获取评论数量)、p.get_thumbs(获取点赞数量)、p.get_thumb_info(@current_user.id)(获取评论数量)都是我们还未定义,之后会在模型文件(app/models/post.rb)里面定义的方法

  • <% if @current_user && p.get_thumb_info(@current_user.id) %>
    代码中的 if @current_user是对点赞功能的权限控制,如果当前有用户登录,就判断这个用户是否给相应的帖子点过赞,并显示相应的点赞图标。如果当前没有用户登录,全部显示未点赞图标(fa-thumbs-up),并且用户点击点赞按钮时,提示「您还未登录,请先登录」

  • <a data-remote="true" href="#" id="reduce" class="fa fa-thumbs-up" style="font-size:30px;">
    我们<a>标签内再加上data-remote="true",实现ajax功能,Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。 点完赞后我们还是想停留在当前页面位置,如果不使用ajax功能,用户点击点赞按钮,整个页面会刷新,影响体验。
    class="fa fa-thumbs-up"是取用的Font Awesome 矢量图标库中的点赞图标,我们在第2步中已经在views/layouts/application.html.erb加载了矢量图标库,具体可以参考菜鸟教程http://www.runoob.com/font-awesome/fontawesome-tutorial.html

5、编辑app/models/post.rb文件,实现我们在views/home/index.html.erb文件中调用的方法:
class Post < ApplicationRecord 
    #定义一个实例方法获取用户名称,可以通过实例对象直接调用,比如:Post.first.get_account_name 
    def get_account_name
      #self代表实例本身,即Post.first这个实例对象
      account_id = self.account_id
      account = Account.find_by(id:account_id)
      name = "此用户未命名"
      if account
        name = account.name
      end
    end

    # 获取帖子最后修改时间
    # 当小于60秒的时候返回时间为xx秒前; 
    # 当小于60分钟大于等于60秒时返回xx分钟前; 
    # 当小于24小时大于等于60分钟时返回xx小时前;
    # 当小于2天大于等于24小时时显示一天前; 
    # 当大于等于2天的时候,显示xx-xx-xx日期;
    def get_updated_at
        updated_at = self.updated_at
        now = Time.now
        #时间间隔秒数
        time_distance = (now - updated_at).to_i
        #判断时间间隔是否小于60秒,是的话,运行if语句下面的代码,
        #不是的话,继续判断elsif对应的条件
        if time_distance < 60
            date = "#{time_distance}秒前"
        #判断时间间隔是否小于60分钟
        elsif time_distance/60 < 60
            date = "#{time_distance/60}分钟前"
        #判断时间间隔是否小于24小时
        elsif time_distance/(60*60) < 24
            date = "#{time_distance/(60*60)}小时前"
        #判断时间间隔是否小于2天
        elsif time_distance/(60*60*24) < 2
            date = "1天前"
        #时间间隔大于2天,会进入else语句下面的代码
        else
            #strftime用于对时间的格式化,"%Y-%m-%d"的日期举例2018-10-11
            date = updated_at.strftime("%Y-%m-%d")
        end
        #最后返回date变量,在get_updated_at方法的时候会返回date变量
        date
    end
    
    #获取评论数,目前还未建立评论表,默认评论数为1
    def get_post_items
      num = 1
    end
    
    #获取点赞数,目前还未建立点赞表,默认点赞数为1
    def get_thumbs
      num = 1
    end
    
    #获取此用户是否给该帖子点过赞,默认为未点过
    def get_thumb_info(account_id)
      boolean = false
    end
end
6、rails c进入控制台,我们创建几条数据,然后启动项目,查看主页面的效果:
#进入控制台
vagrant@vagrant-ubuntu-trusty-64:/vagrant/data_system$ rails c
#创建帖子1--置顶帖
irb(main):001:0> Post.create(head: "第一个帖子", body: "欢迎来到宠物之家论坛欢迎来到宠物之家论坛欢迎来到宠物之家论坛欢迎来到宠物之家论坛欢迎来到宠物之家论坛欢迎来到宠物之家论坛Welcome", account_id: 1, as_type: 2, status: 0)
#创建帖子2--精华帖
irb(main):002:0> Post.create(head: "第二个帖子", body: "欢迎来到宠物之家论坛", account_id: 1, as_type: 1, status: 0)
#创建帖子3--普通帖
irb(main):003:0> Post.create(head: "猫咪拉肚子怎么办?", body: "请问一下猫咪拉肚子怎么办呢?精神和食欲都很好,就是拉肚子,已经持续一个月了,猫瘟和体内有虫的情况都排除,你们遇到过这种情况吗?需要怎么治呢?", account_id: 1, as_type: 0, status: 0)
#创建帖子4--普通帖
irb(main):004:0> Post.create(head: "第三个帖子", body: "请问一下猫咪拉肚子怎么办呢?精神和食欲都很好,就是拉肚子,已经持续一个月了,猫瘟和体内有虫的情况都排除,你们遇到过这种情况吗?需要怎么治呢?", account_id: 6, as_type: 0, status: 0)
#退出控制台
irb(main):005:0>exit
#启动项目
vagrant@vagrant-ubuntu-trusty-64:/vagrant/data_system$ rails s

打开浏览器查看主页面的效果,如下图,说明显示帖子列表功能已经成功了

猜你喜欢

转载自blog.csdn.net/shine_a/article/details/87355932