Rails 101

作者: 阿轲666 | 来源:发表于2017-10-10 21:56 被阅读0次

对自己进入全栈工程师进行一个记录。

前期配置

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>

相关文章

  • rails101再复盘-加深记忆-1

    2.2 开始 配置好基础,新建项目rails new rails101cd rails101git initgit...

  • Rails 101

    对自己进入全栈工程师进行一个记录。 前期配置 rails new rails101git initgit add ...

  • 2018-01-25,27,28

    rails101错: <%= if !current_user %>对:<% if !current_user ...

  • (全栈营/ORID)2018-3-31

    Objective 客观:关于今日的课程,完成了什么? (目前进度:rails101的第二遍练习)完成了rails...

  • (全栈营/ORID)2018-4-01

    Objective 客观:关于今日的课程,完成了什么? (目前进度:rails101的第二遍练习)完成了rails...

  • (全栈营/ORID)2018-4-02

    Objective 客观:关于今日的课程,完成了什么? (目前进度:rails101的第二遍练习)完成了rails...

  • (全栈营/ORID)2018-3-30

    Objective 客观:关于今日的课程,完成了什么? (目前进度:rails101的第二遍练习)完成了rails...

  • 全栈营第二次meetup

    周六第一次做完复制粘贴版的rails101,然后第二遍手打版rails102,结果在显示hello world时出...

  • (全栈营/ORID)2018-3-29

    2018-3-29 ORID Objective 客观:关于今日的课程,完成了什么? (目前进度:rails101...

  • 2019-03-19全栈营ORID

    Objective 完成了什么? ---完成了Rails101课程的前4课 Reflective 你要如何形容今天...

网友评论

    本文标题:Rails 101

    本文链接:https://www.haomeiwen.com/subject/dynbyxtx.html