对自己进入全栈工程师进行一个记录。
前期配置
rails new rails101
git init
git add .
git commit -m "Initial Commit"
穿衣服Bootstrap
gem 'bootstrap-sass'
Bootstrap 的 CSS 套件
- 裝進專案裡面 app/assets/stylesheets/application.scss
@import "bootstrap-sprockets";
@import "bootstrap";
mkdir app/views/common
touch app/views/common/_navbar.html.erb
app/views/common/_navbar.html.erb
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/">Rails 101</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li>
<%= link_to("登录", '#') %>
</li>
</ul>
</div>
</div>
</nav>
touch app/views/common/_footer.html.erb
app/views/common/_footer.html.erb
<footer class="container" style="margin-top: 100px;">
<p class="text-center">Copyright ©2017 Rails101
<br>Design by
<a href="http://courses.growthschool.com/courses/rails-101/" target=_new>xdite</a>
</p>
</footer>
app/views/layouts/application.html.erb
layout用来做后台管理
<body>
<div class="container-fluid">
<%= render "common/navbar" %>
<%= yield %>
</div>
<%= render "common/footer" %>
</body>
</html>
将alert的js套件”挂”进项目的步骤、
- 修改 app/assets/javascripts/application.js加入
//= require bootstrap/alert
touch app/views/common/_flashes.html.erb
app/views/common/_flashes.html.erb
<% if flash.any? %>
<% user_facing_flashes.each do |key, value| %>
<div class="alert alert-dismissable alert-<%= flash_class(key) %>">
<button class="close" data-dismiss="alert">×</button>
<%= value %>
</div>
<% end %>
<% end %>
touch app/helpers/flashes_helper.rb
app/helpers/flashes_helper.rb
module FlashesHelper
FLASH_CLASSES = { alert: "danger", notice: "success", warning: "warning"}.freeze
def flash_class(key)
FLASH_CLASSES.fetch key.to_sym, key
end
def user_facing_flashes
flash.to_hash.slice "alert", "notice", "warning"
end
end
在layout文件中 <%= yield %> 前加入
<%= render "common/flashes" %>
建立群架构
rails g model group title:string description:text
rake db:migrate
rails g controller groups
app/controllers/groups_controller.rb
class GroupsController < ApplicationController
def index
@groups = Group.all
end
def show
@group = Group.find(params[:id])
end
def edit
@group = Group.find(params[:id])
end
def new
@group=Group.new
end
def create
@group= Group.new(group_params)
if @group.save
redirect_to groups_path
else
render :new
end
end
def update
@group=Group.find(params[:id])
if @group.update(group_params)
redirect_to groups_path, notice: "Update Success"
else
render :edit
end
end
def destroy
@group=Group.find(params[:id])
@group.destroy
flash[:alert]= "Group deleted"
redirect_to groups_path
end
private
def group_params
params.require(:group).permit(:title, :description)
end
end
touch app/views/groups/index.html.erb
<div class="col-md-12">
<div class="group">
<%= link_to("New group", new_group_path, class: "btn btn-primary pull-right") %>
</div>
<table class="table table-hover">
<thead>
<tr>
<td>#</td>
<td>Title</td>
<td>Description</td>
</tr>
</thead>
<tbody>
<% @groups.each do |group| %>
<tr>
<td>#</td>
<td><%= link_to(group.title, group_path(group)) %></td>
<td><%= group.description %></td>
<td>
<%= link_to("Edit", edit_group_path(group), class: "btn btn-sm btn-default")%>
<%= link_to("Delete", group_path(group), class: "btn btn-sm btn-default",
method: :delete, data: { confirm: "Are you sure?" } )%>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
config/routes.rb
resources :groups do
root 'groups#index'
end
- 测试一下
rails c
Group.create(title: "Board 1", description: "Board 1 body")
手动实作讨论群的“新增”“修改”“删除”功能
touch app/views/groups/new.html.erb
<div class= "col-md-4 col-md-offset-4">
<h2> 新增讨论版 </h2>
<hr>
<%= render "form" %>
</div>
touch app/views/groups/edit.html.erb
<div class="col-md-4 col-md-offset-4">
<h2>编辑讨论版</h2>
<hr>
<%= render "form" %>
</div>
touch app/views/groups/show.html.erb
<div class="col-md-12">
<div class="group">
<%= link_to("Edit", edit_group_path(@group), class: "btn btn-primary pull-right")%>
</div>
<h2><%= @group.title %></h2>
<p><%= @group.description %></p>
</div>
装gem 'simple_form'
- step1: gem 'simple_form'
- step2: bundle install
- step3: rails generate simple_form:install --bootstrap
touch app/views/groups/_form.html.erb
<%= simple_form_for @group do |f| %>
<div class="form-group">
<%= f.input :title, input_html: { class: "form-control"} %>
<%= f.input :description, input_html: { class: "form-control"} %>
</div>
<%= f.submit "Submit", class: "btn btn-primary", date: {disable_with: "Submiting..."} %>
<% end %>
做会员系统
gem 'devise'
bundle install
rails g devise:install
rails g devise user
rake db:migrate
然后重开 rails server
修改app/controllers/groups_controller.rb
before_action :authenticate_user! , only: [:new]
下拉菜单
app/views/common/_navbar.html.erb
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/">点我试试呀</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<% if !current_user %>
<li><%= link_to("注册", new_user_registration_path) %> </li>
<li><%= link_to("登录", new_user_session_path) %></li>
<% else %>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
Hi!, <%= current_user.email %>
<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li> <%= link_to("退出", destroy_user_session_path, method: :delete) %> </li>
</ul>
</li>
<% end %>
</li>
</ul>
</div>
</div>
</nav>
- 加入js套件
//= require bootstrap/dropdown
让“群组”与“使用者”产生关联
rails g migration add_user_id_to_group
db/migrate/一串数字_add_user_id_to_group
add_column :groups, :user_id, :integer
rake db:migrate
app/models/user.rb
has_many :groups
app/models/group.rb
belongs_to :user
validates :title, presence: true
app/controllers/groups_controller.rb
before_action :authenticate_user! , only: [:new, :create]
app/controllers/groups_controller.rb
在 create 中,多加入一行
@group.user = current_user
修改 app/views/groups/index.html.erb 然后把 Creator 的信息加进去
<td>Creator </td>
。。。。。。
<td> <%= group.user.email %> </td>
如果出现报错就如下处理
rails console
Group.delete_all
- 路人不应该可以看到“编辑”“删除”按钮
app/views/groups/index.html.erb
<% if current_user && current_user == group.user %>
<% end %>
- 修改 app/controllers/groups_controller.rb
before_action :authenticate_user! , only: [:new, :create, :edit, :update, :destroy]
before_action :find_group_and_check_permission, only: [:edit, :update, :destroy]
打开 app/controllers/groups_controller.rb 在 private 下,新增一个 find_group_and_check_permission
def find_group_and_check_permission
@group = Group.find(params[:id])
if current_user != @group.user
redirect_to root_path, alert: "You have no permission."
end
end
- 拔掉路人show里面的edit
- 修改 app/views/groups/show.html.erb ,然后加入
<% if current_user && current_user == @group.user %>
设计Post 的 model 架构
rails g model post content:text group_id:integer user_id:integer
rake db:migrate
- Group / Post / User 三者间的关系
group.rb
has_many :posts
user.rb
has_many :posts
post.rb
belongs_to :user
belongs_to :group
将 ==resources :posts== 加入 resources :groups 内
Rails.application.routes.draw do
devise_for :users
resources :groups do
resources :posts
end
root 'groups#index'
end
rake routes
修改 app/views/groups/show.html.erb
<%= link_to("Write a Post", new_group_post_path(@group), class: "btn btn-default pull-right")%>
rails g controller posts
新增 new 与 create action 在posts_controllerapp/controllers/posts_controller.rb
class PostsController < ApplicationController
before_action :authenticate_user!, :only => [:new, :create]
def new
@group = Group.find(params[:group_id])
@post = Post.new
end
def create
@group = Group.find(params[:group_id])
@post = Post.new(post_params)
@post.group = @group
@post.user = current_user
if @post.save
redirect_to group_path(@group)
else
render :new
end
end
private
def post_params
params.require(:post).permit(:content)
end
end
touch app/views/posts/new.html.erb
<h2 class="text-center">新增文章</h2>
<div class="col-md-4 col-md-offset-4">
<%= simple_form_for [@group,@post] do |f| %>
<div class="form-group">
<%= f.input :content, input_html: { class: "form-control"} %>
</div>
<div class="form-actions">
<%= f.submit "Submit", disable_with: "Submiting...", class: "btn btn-primary"%>
</div>
<% end %>
</div>
修改 app/controllers/groups_controller.rb的show里面
@posts = @group.posts
修改groups/show.html.erb
<table class="table">
<thead>
<tr>
<th>文章内容</th>
<th>发表者</th>
<th>发表时间</th>
</tr>
</thead>
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= post.content %></td>
<td><%= post.user.email %></td>
<td><%= post.created_at %></td>
</tr>
<% end %>
</tbody>
</table>
限制 post 的 content 要是为空,就不得送出修改 app/models/post.rb 加入
validates :content, presence: true
发表时间“倒序”排列
修改 app/models/post.rb,加入一行
scope :recent, -> { order("created_at DESC")}
然后修改 app/controllers/groups_controller.rb 中的 show,变成
@posts = @group.posts.recent
加入文章分页功能
gem 'will_paginate'
bundle install
rails server
- 修改 app/controllers/groups_controller.rb 中的 show
@posts = @group.posts.recent.paginate(:page => params[:page], :per_page => 5)
- 修改 app/views/groups/show.html.erb
在最下面 </table> 下加入以下三行代码:
<div class="text-center">
<%= will_paginate @posts %>
</div>
“加入群组”或“退出群组”
gem、controller、show三部分改动
rails g model group_relationship group_id:integer user_id:integer
rake db:migrate
- 修改app/views/groups/show.html.erb
<span class="pull-right">
<% if current_user && current_user.is_member_of?(@group) %>
<label class="label label-success"> 群组成员 </label>
<%= link_to("想要Quit Group", quit_group_path(@group), method: :post, class: "btn btn-default") %>
<% else %>
<label class="label label-warning"> 不是群组成员 </label>
<%= link_to("Join123 Group", join_group_path(@group), method: :post, class: "btn btn-default") %>
<% end %>
</span>
- app/models/user.rb
has_many :group_relationships
has_many :participated_groups, :through => :group_relationships, :source => :group
def is_member_of?(group)
participated_groups.include?(group)
end
def join!(group)
participated_groups << group
end
def quit!(group)
participated_groups.delete(group)
end
- app/models/group_relationship.rb
belongs_to :group
belongs_to :user
- app/models/group.rb
has_many :group_relationships
has_many :members, through: :group_relationships, source: :user
- app/controllers/groups_controller.rb
def join
@group = Group.find(params[:id])
if !current_user.is_member_of?(@group)
current_user.join!(@group)
flash[:notice] = "加入本讨论版成功!"
else
flash[:warning!] = "你已经是本讨论版成员!"
end
redirect_to group_path(@group)
end
def quit
@group = Group.find(params[:id])
if current_user.is_member_of?(@group)
current_user.quit!(@group)
flash[:alert] = "已退出本讨论版!"
else
flash[:warning] = "你不是本讨论版成员,怎么退出 XD"
end
redirect_to group_path(@group)
end
- 修改位於第二行的 before_action ,加入 join 和 quit 也需要验证
config/routes.rb
resources :groups do
member do
post :join
post :quit
end
让 User 在建立 group 后自动成为 group 的一员
- app/controllers/groups_controller.rb
current_user.join!(@group)
使用者可以在“自己的后台”看过曾经发表的文章、以及创立的社团
rails g controller account/groups
config/routes.rb
namespace :account do
resources :groups
end
在“下拉选单选项”中多加入一个My Groups:
- app/views/common/_navbar.html.erb
<li> <%= link_to("My Groups", account_groups_path) %></li>
<li class="divider"> </li>
- 记得要加入: before_action :authenticate_user!,限制必须要得登录使用者,才能看。
app/controllers/account/groups_controller.rb
before_action :authenticate_user!
def index
@groups = current_user.participated_groups
end
制作管理者观看后台界面
touch app/views/account/groups/index.html.erb
<div class="col-md-12">
<h2 class="text-center"> 我加入的讨论版 </h2>
<table class="table">
<thead>
<tr>
<th> # </th>
<th> Title </th>
<th> Description </th>
<th> Post Count </th>
<th> Last Update </th>
</tr>
</thead>
<tbody>
<% @groups.each do |group| %>
<tr>
<td> # </td>
<td> <%= link_to(group.title, group_path(group)) %> </td>
<td> <%= group.description %> </td>
<td> <%= group.posts.count %> </td>
<td> <%= group.updated_at %> </td>
</tr>
<% end %>
</tbody>
</table>
</div>