借助 inherited_resources 编写后台模块 - tianlu1677/tianlu1677.github.io GitHub Wiki

主要使用的gem

  • selec2
  • inherited_resources
  • haml
  • ransack

下面以书籍管理这个模块为例子

常用步骤

  • 1.生成model,编写数据库

    $ rails g model book

    修改db中的migration文件,然后执行 rake db:migrate

  • 2.建立关联

    class Course < ActiveRecord::Base
      has_many :books_courses, dependent: :destroy
      has_many :books, through: :books_courses
    end
    
    class Book < ActiveRecord::Base
      has_many :books_courses, dependent: :destroy
      has_many :courses, through: :books_courses
    end
    
  • 3.写routes

    resources :books
    
  • 4.编写controller内容

   # -*- encoding : utf-8 -*-
   class BooksController <  ResourceController
     def index
       @q = resource_class.search(params[:q]) # 
       respond_to do |f|
         f.html{  @books = @q.result.page(params[:page] || 1) }
         f.xls{  send_xls_data(@q.result,attributes,attributes) and return }
       end
     end
   
     private  
     def permitted_params
       params.permit(:book => [:name, :author, :publisher, :buy_link, :status, image_attributes: [:link]])
     end
   
     def attributes
       %w(name author publisher buy_link status image_link_url)
     end
   end
主要修改上面的index的中@books替换成当前对象集合
下面的强参数中,写入当前对应的的参数,包括has_one的参数的属性

下面的方法attributes 是为了在view中遍历所包含的属性
  • 5.修改国际化 config/locales/zh-CN.yml 主要修改
    enumerize:
      user:
        status:
          active: 激活
          forbidden: 禁闭
    
    
    book:
        <<: *action_labels
        
    activerecord:
        models:
          book: 书籍
        attributes:
          book:
            name: 书名
            author: 作者
            publisher: 出版社
            buy_link: 购买链接
            status: 书籍状态
            image_link_url: 书籍封面
  • 6.可以获得最常见的页面,可以增删改查

因为继承了inherited_resoures,

class BooksController <  ResourceController

end

class ResourceController < ApplicationController
  inherit_resources
end

从而使book有七个方法,如果没有编写view的话,会继承了view/resources/*.haml的文件 这里使用的是haml编写的。

下面是haml语法的简单介绍,标签用%class. id# ,erb中 <% %>-<%= %>

<div id='content'>
  <div class='left column'>
    <h2>Welcome to our site!</h2>
    <p><%= print_information %></p>
  </div>
  <div class="right column">
    <%= render :partial => "sidebar" %>
  </div>
</div>

-----------------------

#content
  .left.column
    %h2 Welcome to our site!
    %p= print_information
  .right.column
    = render :partial => "sidebar"
  • 7.编写view

在大部分情况下,可以直接使用resoure的view,但是如果有嵌套的图片的话,则需要对原来的视图进行覆盖 在 views/books中,覆写了 form index show

  • 8.增加入口,左侧边栏 在 application/left.html.erb中合适的位置

添加合适

<li><%= link_to books_path do -%><i class="fa fa-angle-double-right"></i> 书籍管理<% end if can? :read, Book -%></li>

基本上一个完整的模块增加完成。

图片模块

  • 0.添加gem 使用的是 carrierwave gem 'carrierwave'

  • 1.生成uploader 文件

rails generate uploader Book(文件名)
# app/uploaders/book_uploader.rb 在下面产生新文件
  • 2.在 model 中增加一个类名为 BookImage
class BookImage < Asset

  mount_uploader :link, BookImageUploader
  
end

将该图片挂载在 link 字段上,而BookImage继承了Asset

class Asset < ActiveRecord::Base

  belongs_to :viewable, polymorphic: true

end

这里使用多态(polymorphic) 在 belongs_to 中指定使用多态,可以理解成创建了一个接口,可供任何一个模型使用。 AC关联

  • 3.修改嵌套类中
class Book < ActiveRecord::Base
  extend Enumerize

  enumerize :status, in: ['0', '1', '2'], default: '0'

  has_many :books_courses, dependent: :destroy
  has_many :courses, through: :books_courses

  has_one :image, class_name: "BookImage", as: :viewable, dependent: :destroy 
  # :image, 这在数据库中没有这个字段,可以理解为image为Book_image类的特例化,来指定模型名,同时
  # 这里的viewable 为BookImage, viewable来区分该图片属于不同的类
  accepts_nested_attributes_for :image, reject_if: lambda { |a| a[:link].blank? }, :allow_destroy => true
  # 嵌套属性,如果图片为空,则不会创建该记录;允许删除,允许在删除的时候,也删除图片
  delegate :link_url, to: :image, prefix: true, allow_nil: true
  
  # delegate是将 image里面的link_url方法暴露给Book,而link_url是carr自带的方法,
  # prefix为true的话,则是 image_link_url
  validates :name, :author, :publisher, :buy_link, presence: true

end
    1. 修改form中字段名称
= f.simple_fields_for :image, f.object.image ? f.object.image : f.object.build_image do |image_form|
   = image_form.input :link, required: f.object.new_record?, hint: "请上传书籍图片,格式为.png等,尺寸要求为300*300"
  • 4.国际化 zh-CN.yml
models:
    book_image:
      link_url: 书籍图片
      link: 书籍图片  
    book:
      image_link_url: 书籍图片
    

搜索ransack

  • 0.安装gem gem 'ransack'

  • 1.在controller中写

class BooksController <  ResourceController
  
  def index
    @q = resource_class.search(params[:q])
    # 这句是根据参数,查询出的结果赋值给resource_class 即 @books
    # respond_to 是将数据,转化为不同的格式,其中是html,xls是为了导出数据
    respond_to do |f|
      f.html{  @books = @q.result.page(params[:page] || 1) }
      f.xls{  send_xls_data(@q.result,attributes,attributes) and return }
    end
  end

end
  
  • 2.修改views/books/index

search_form_for 是ransack专用的form

上面的搜索条

= search_form_for @q do |f|
  = f.label :name_cont  # name中包含输入的内容, cont => contain
  = f.text_field :name_cont
  = f.label :author_cont
  = f.text_field :author_cont
  = f.submit class: 'btn btn-primary'
%br

标题栏的排序

%th.text-center= "排序"
- (attributes ).each do |attr|
  = content_tag :th, sort_link(@q, attr)
%th= "操作"

拖动排序

views/books/_index

%table{id: "collection_table", class: "table table-bordered table-striped sortable", :"data-sortable-link" => update_positions_resource_index_path(resource_class: "Book") }

导出xls

select2-rails

参见证书使用
⚠️ **GitHub.com Fallback** ⚠️