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>
    

    相关文章

      网友评论

        本文标题:Rails 101

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