打算后面写一些功能实现方面的小文章,详见目录。
今天先来一个收藏功能+Ajax优化.
目录
- 给活动添加收藏功能,并使用Ajax进行优化
- 给活动Events添加分类筛选
- 添加省市自治区地址, 并实现热门城市筛选
- 添加时间筛选
- 添加评论区,并使用ajax优化
- 实作活动申请
- 在个人中心实作密码修改
正文
先上效果图:
咱分两步走:
Step1、制作收藏功能
新建一个favorite model,终端运行:
rails g model favorite user_id:integer event_id:integer rake db:migrate
建立favorite与user,event的关系
在app/models/favorite.rb中,加入:
belongs_to :user belongs_to :event
在
app/models/event.rb
中,加入:has_many :favorites has_many :fans, through: :favorites, source: :user
在
app/models/user.rb
中,加入:has_many :favorites has_many :favorite_events, through: :favorites, source: :event
在
app/models/user.rb
中,加入是否已收藏活动的判断,及收藏与取消收藏的method:def is_favorite_of?(event) favorite_events.include?(event) end def favorite!(event) favorite_events << event end def unfavorite!(event) favorite_events.delete(event) end
修改
config/routes.rb
中events 部分:resources :events do put :favorite, on: :member end
在需要添加收藏的页面,比如event的show或者index,加上收藏及取消收藏,代码以index页面为例:
【这里,建议你安装
font-awesome-rails
这个gem,如果没有,也没关系,用button代替即可】装了
font-awesome-rails
,可以这么来:<% @events.each do |event| %> ....... <% if current_user && current_user.is_favorite_of?(event)%> <%= link_to favorite_event_path(event,type: "unfavorite"), method: :put do %> <i class="fa fa-star"> 已收藏 </i> <% end %> <% else %> <%= link_to favorite_event_path(event,type: "favorite"), method: :put do %> <i class="fa fa-star-o"> 收藏</i> <% end %> <% end %> .......
没有装,咱可以这么来:
<% @events.each do |event| %> ....... <% if current_user && current_user.is_favorite_of?(event)%> <%= link_to('已收藏',favorite_event_path(event,type: "unfavorite"), method: :put, class: "btn btn-default") %> <% else %> <%= link_to('收藏',favorite_event_path(event,type: "favorite"), method: :put, class: "btn btn-success") %> <% end %> .......
编辑
app/controller/events_controller.rb
,加上favorite方法,同时在before_action中加上favoritebefore_action :authenticate_user!, only: [:favorite, .....] ..... def favorite @event = Event.find(params[:id]) type = params[:type] if type == "favorite" current_user.favorite!(@event) else type == "unfavorite" current_user.unfavorite!(@event) end redirect_to :back end ......
到这里,功能基本OK了,下面我们请上Ajax.
Step2、Ajax优化
目标:实现快速收藏,同时显示收藏人数
编辑
app/views/events/index.html.erb
,把原来用作收藏的html部分删除,放入partial中:<% @events.each do |event| %> ....... - <% if current_user && current_user.is_favorite_of?(event)%> - <%= link_to('已收藏',favorite_event_path(event,type: "unfavorite"), method: :put, class: "btn btn-default") %> - <% else %> - <%= link_to('收藏',favorite_event_path(event,type: "favorite"), method: :put, class: "btn btn-success") %> - <% end %> + <div id="favorite-<%= event.id %>"> + <%= render :partial => "favorite", :locals => {:event => event }%> + </div> .......
新建
app/views/events/_favorite.html.erb
, 添加如下代码到_favorite.html.erb
中:<% if current_user && current_user.is_favorite_of?(event) %> <%= link_to favorite_event_path(event,type: "unfavorite"), method: :put, :remote => true do %> <i class="fa fa-star"> 已收藏 (<span id="favorite-counts-<%= event.id %>"><%= event.favorites.count%></span>)</i> <% end %> <% else %> <%= link_to favorite_event_path(event,type: "favorite"), method: :put, :remote => true do %> <i class="fa fa-star-o"> 收藏 (<span id="favorite-counts-<%= event.id %>"><%= event.favorites.count%></span>)</i> <% end %> <% end %>
【这里默认已安装了
font-awesome-rails
这个gem】编辑
app/controllers/events_controller.rb
, 去掉favorite中的redirect_to:..... def favorite @event = Event.find(params[:id]) type = params[:type] if type == "favorite" current_user.favorite!(@event) else type == "unfavorite" current_user.unfavorite!(@event) end - redirect_to :back end ......
新建
app/views/events/favorite.js.erb
,添加如下代码到favorite.js.erb
中:str = "<%=j render :partial => "favorite", :locals => {:event => @event } %>"; $("#favorite-<%= @event.id %>").html(str); $("#favorite-counts-<%= @event.id %>").html("<%= @event.favorites.count %>");
啦啦啦,大功告成!!
参考文章:如何做出收藏工作的功能?
稍稍加个餐:
BTW,简单提一个在用 Ajax 优化时,遇到的bug。
在未登录的情况,用户进行点赞及收藏,应该跳出登录界面,但网站没有任何反应,而你的controller里面已经有了before_action :authenticate_user!
, 貌似没起效果,怎么破?
上图:
附上服务器报错信息:
Google后,会发现一堆相关的,包括在config/initializers/devise
设置config.http_authenticatable_on_xhr = false
, 修改routes.rb
的,设置CSRF token的……试了好些个,没能解决。比较好笑的是,最后找到的解决办法,有些过于简单,哈哈。
附上:
在app/controllers/events_controller.rb
中,添加如下代码:
class EventsController < ApplicationController
before_action :check_user, only: [:favorite, :like]
......
def check_user
return if user_signed_in?
redirect_to new_user_session_path, error: '请先登录'
end
......
end
现在点击收藏或点赞,会跳转到登录页面,OK!