这是功能实现的第六篇,扯一扯如何实作活动申请.
目录
- 给活动添加收藏功能,并使用Ajax进行优化
- 给活动Events添加分类筛选
- 添加省市自治区地址, 并实现热门城市筛选
- 添加时间筛选
- 添加评论区,并使用ajax优化
- 实作活动申请
- 在个人中心实作密码修改
正文
具体说,是实作以下两个功能:
- 用户可申请参与活动
- 如果活动已过期,则无法申请,显示已结束;
- 如果人数已满,则显示活动已经满员,报名截止;
- 既未过期,也没有满员,则用户可申请参与活动;
- 用户可以查看自己的申请列表
一步步来:
BTW,请无视CSS部分,只讲如何实作功能。
Step1、 用户可以申请参与活动
效果图:
新建model apply_event,终端:
rails g model apply_event user_id:integer event_id:integer
建立apply_event, user, event三者之间的关系:
在
app/models/apply_event.rb
中添加:class ApplyEvent < ApplicationRecord + belongs_to :user + belongs_to :event end
在
app/models/event.rb
中添加:...... has_many :apply_events has_many :appliers, :through => :apply_events, :source => :user ......
在
app/models/user.rb
中添加:...... has_many :apply_events has_many :applied_events, through: :apply_events, source: :event ......
用户可以申请参加活动或取消申请
在
app/models/user.rb
中添加:...... def apply_already?(event) applied_events.include?(event) end def apply!(event) applied_events << event end def cancel!(event) applied_events.delete(event) end ......
在
app/controllers/events_controller.rb
中添加:class EventsController < ApplicationController ...... def apply @event = Event.find(params[:id]) type = params[:type] if type == "apply" current_user.apply!(@event) else type == "cancel" current_user.cancel!(@event) end redirect_to :back end ...... end
申请参加活动,需要用户在登录状态下,修改
app/controllers/events_controller.rb
的before_action :authenticate_user!
部分,加上apply- before_action :authenticate_user!, only: [:new, :create,.....] + before_action :authenticate_user!, only: [:apply,:new, :create,.....]
修改
config/routes.rb
, 添加如下代码:...... resources :events do ...... + put :apply, on: :member end ......
修改
app/views/events/show.html.erb
, 添加如下代码:...... <% if @event.end_time < Time.now %> <label class="label label-default event-over">活动已结束</label> <% elsif @event.appliers.count >= @event.limited_num %> <label class="label label-default event-over">活动已满员</label> <% else %> <% if current_user && current_user.apply_already?(@event) %> <%= link_to("取消申请", apply_event_path(@event, type: "cancel"), method: :put, class: "btn btn-default event-apply")%> <% else %> <%= link_to("申请赴约", apply_event_path(@event, type: "apply"), method: :put, class: "btn btn-success event-apply")%> <% end %> <% end %> ......
现在看看,可以实现申请及取消申请了。但是,你很快就会发现,点击按钮后页面会refresh一下,这个不好不好,我们请上ajax。
使用ajax来优化
新增
app/views/events/_apply.html.erb
,app/views/events/apply.js.erb
修改
app/views/events/show.html.erb
, 给这块要动态变化的区域加上ID+ <div class="col-md-2" id="apply-<%= @event.id %>"> - <% if @event.end_time < Time.now %> - <label class="label label-default event-over">活动已结束</label> - <% elsif @event.appliers.count >= @event.limited_num %> - <label class="label label-default event-over">活动已满员</label> - <% else %> - <% if current_user && current_user.apply_already?(@event) %> - <%= link_to("取消申请", apply_event_path(@event, type: "cancel"), method: :put, class: "btn btn-default event-apply")%> - <% else %> - <%= link_to("申请赴约", apply_event_path(@event, type: "apply"), method: :put, class: "btn btn-success event-apply")%> - <% end %> - <% end %> + <%= render :partial => "apply", :locals => {:event => @event }%> + </div>
编辑
app/views/events/_apply.html.erb
, 添加如下代码:<% if event.end_time < Time.now %> <label class="label label-default event-over">活动已结束</label> <% elsif event.appliers.count >= event.limited_num %> <label class="label label-default event-over">活动已满员</label> <% else %> <% if current_user && current_user.apply_already?(event) %> <%= link_to apply_event_path(event, type: "cancel"), method: :put, :remote => true do %> <span class="btn btn-default event-apply">取消申请</span> <% end %> <% else %> <%= link_to apply_event_path(event, type: "apply"), method: :put, :remote => true do %> <span class="btn btn-success event-apply">申请赴约</span> <% end %> <% end %> <% end %>
编辑
app/views/events/apply.js.erb
, 添加如下代码:str = "<%=j render :partial => "apply", :locals => {:event => @event } %>"; $("#apply-<%= @event.id %>").html(str);
编辑
app/controllers/events_controller.rb
, 拿掉apply的redirect_to...... def apply ...... # redirect_to :back end ......
现在试试,可以快速申请,快速取消啦,棒棒哒!!
Step2、 用户可以查看自己的申请列表
效果图:
这部分就比较简单啦。
新增controller,终端运行:
rails g controller account::apply_events
修改
config/routes.rb
, 添加如下代码:...... namespace :account do ...... + resources :apply_events end ......
编辑
app/controllers/account/apply_events_controller.rb
,添加class Account::ApplyEventsController < ApplicationController before_action :authenticate_user! def index @events = current_user.applied_events end end
新增
app/views/account/apply_events/index.html.erb
, 添加如下代码:
<h1 class="text-center">我的申请</h1>
<div class="col-md-10 col-md-offset-1" style="margin-top: 20px;">
<table class="table table-bordered">
<thead>
<tr>
<th>活动名称</th>
<th>开始时间</th>
<th>结束时间</th>
<th>地点</th>
<th>主办方</th>
<th>类别</th>
<th>人数限额</th>
<th>剩余名额</th>
<th>状态</th>
</tr>
</thead>
<tbody>
<% @events.each do |event| %>
<tr>
<td>
<% link_to event_path(event)%>
<% if event.logo.present? %>
<%= link_to image_tag(event.logo.thumb.url, class:"event_logo_sm")%>
<% else %>
<%= link_to image_tag("http://placehold.it/100x100&text=No Pic", class: "event_logo_sm")%>
<% end %>
<%= link_to(event.title, event_path(event)) %></td>
<td><%= event.start_time %></td>
<td><%= event.end_time %></td>
<td><%= event.address %></td>
<td><%= event.sponsor %></td>
<td><%= event.category.name %></td>
<td><%= event.limited_num %></td>
<td><%= event.limited_num - event.appliers.count %></td>
<td><%= t(event.status, :scope => "event.status") %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
<!-- 分页 -->
<div class="text-center">
<%= will_paginate @events, renderer: BootstrapPagination::Rails, :previous_label => '上一页', :next_label => '下一页' %>
</div>
编辑
app/views/common/_navbar.html.erb
,加上我的申请入口:...... + <li><%= link_to(" 我的申请",account_apply_events_path(current_user), class: "btn btn-default")%></li> ......
试试看,可以啦!