12/08/2018, 13:15

Xây dựng trang quản lí website sử dụng rails_admin

Mở đầu Với hầu hết các trang web hiện nay, một trang admin để quản lí là không thể thiếu. Để tự tay xây dựng hoàn thiện một trang admin là không hề dễ dàng và tốn không ít thời gian. Tuy nhiên đối với những lập trình viên Ruby on Rails thì chúng ta đã có một gem rất mạnh để hỗ trợ việc này đó là ...

Mở đầu

Với hầu hết các trang web hiện nay, một trang admin để quản lí là không thể thiếu. Để tự tay xây dựng hoàn thiện một trang admin là không hề dễ dàng và tốn không ít thời gian. Tuy nhiên đối với những lập trình viên Ruby on Rails thì chúng ta đã có một gem rất mạnh để hỗ trợ việc này đó là rails_admin. Và ngày hôm nay mình sẽ cùng các bạn xây dựng demo một trang admin sử dụng rails_admin và một số gem khác như Cancancan, Ckeditor, Devise. Mình sẽ chỉ tập trung vào phần trang admin và sẽ không có phần front_end cho ứng dụng demo này.

Chúng ta sẽ xây dựng ứng dụng demo với 2 model chính là User và Post như sau:

Screenshot from 2016-02-29 18:15:37.png

Ngoài ra còn một số bảng và trường khác sẽ được thêm vào khi ta thêm các gem.

Đầu tiên chúng ta cần thêm gem devise để tạo một giao diện đăng nhập, đăng kí đơn giản phục vụ cho việc phân quyền User trên trang admin. Bạn có thể tham khảo về cách sử dụng gem deivse ở đây

Cài đặt rails_admin

  • Thêm dòng gem 'rails_admin' vào gemfile
  • Chạy lệnh bundle install
  • Chạy lệnh rails g rails_admin:install và chọn namespace khi được hỏi. Nếu bạn không chọn gì, giá trị namespace sẽ được để mặc định là /admin

Đây là giao diện của rails_admin

Screenshot from 2016-02-29 15:24:26.png

Cấu hình rails_admin

Mỗi trang web sẽ có thiết kế cơ sở dữ liệu khác nhau nên bạn sẽ cần config khá nhiều và đây mới là bước quan trọng nhất khi sử dụng rails_admin

Các config cho rails_admin sẽ được viết trong file rails_admin.rb

Thêm bớt và thay đổi các trường

Mặc định rails_admin sẽ hiển thị tất cả các trường của model. Để chọn những trường nào được hiển thị trong action nào ta có thể config như sau:

RailsAdmin.config do |config|
  config.model 'Post' do
    edit do
      field :title
      field :content
    end
  end
end

Với đoạn config trên thì khi chỉnh sửa một bài đăng (action edit), ta sẽ chỉ thay đổi 2 trường là title và content. Một số trường không cần thay đổi như updated_at hay created_at sẽ được ẩn đi.

Ckeditor

Đối với những trang web cần viết những bài viết dài và có bố cục rõ ràng thì một trình soạn thảo sẽ là cần thiết để hỗ trợ tốt hơn cho việc viết bài. Ở đây mình sẽ sử dụng gem ckeditor để soạn thảo nội dung cho Post.

Cài đặt ckeditor

  • Thêm 3 gem sau vào gemfile:

    gem 'ckeditor'

    gem 'carrierwave'

    gem 'mini_magick'

    carrierwave và mini_magick sẽ được dùng để upload các file như ảnh, âm thanh cho ckeditor

  • Chạy lệnh: bundle install

  • Chạy lệnh: rails generate ckeditor:install --orm=active_record --backend=carrierwave

  • Thêm dòng sau vào file config/routes.rb để mount Ckeditor::Engine

  • Include ckeditor javascripts trong file app/assets/javascripts/application.js

    //= require ckeditor/init
  • Để dùng ckeditor soạn nội dung cho trường content của model Post ta cần thêm đoạn config sau trong file rails_admin.rb
  config.model Post do
     edit do
       field :title
       field :content, :ck_editor
     end
  end

Giờ thì ta đã có thể dùng ckeditor để soạn thảo nội dung cho bài viết

Screenshot from 2016-02-29 16:28:56.png

Một lưu ý đó là khi bạn sử dụng ckeditor, nội dung của bài viết sẽ tự động được thêm các thẻ html để bố cục bài viết. Vậy nên khi hiển thị các trường này bạn cần sử dụng hàm html_safe

    <%= post.content.html_safe %>

Bạn có thể tìm hiểu thêm về ckeditor tại đây

Set default value

Giả sử khi bạn muốn tạo một bài viết và muốn lưu luôn user_id của current_user cho bài viết được tạo. Do sử dụng rails_admin nên bạn sẽ không thể vào controller của rails_admin và build để tạo các relation như bình thường được. Thay vào đó, bạn sẽ cần gán cho trường user_id của post luôn nhận giá trị default là id của current_user bằng đoạn code sau.

    config.model Post do
      edit do
        field :user_id, :hidden do
          default_value do
            bindings[:view]._current_user.id
          end
        end
      end
    end

Phân quyền sử dụng cancancan

Đối với các trang admin thì việc phân quyền cho những người dùng khác nhau là rất cần thiết. Ở đây chúng ta sẽ dùng gem cancancan để phân quyền đối với từng user có role khác nhau.

Cài đặt gem cancancan

  • Thêm vào gemfile: gem "cancancan"
  • bundle install
  • rails g cancan:ability
  • Config rails_admin với cancancan
    # in config/initializers/rails_admin.rb
    RailsAdmin.config do |config|
      config.authorize_with :cancan
    end
  • Để người dùng có thể truy cập vào trang dashboard của rails_admin ta cần thêm dòng sau đối với những user có role cần được cấp quyền
    can :access, :rails_admin
    can :dashboard
  • Bạn cũng có thể phân quyền cho từng kiểu người dùng đối với từng model khác nhau. Dưới đây là file ability.rb mình phân quyền theo role của user với 3 role khác nhau là member, publisher, super admin
    class Ability
      include CanCan::Ability

      def initialize user
        user ||= User.new

        case user.role
        when "super admin"
          can :access, :rails_admin
          can :dashboard
          can :manage, :all
        when "publisher"
          can :access, :rails_admin
          can :dashboard
          can :read, :post
          can :update, :post, :user_id => user.id
        when "member"
        end
      end
    end

Theo cách phân quyền trên đây thì super admin sẽ có toàn quyền đối với tất cả các models, publisher sẽ có quyền xem danh sách bài viết và chỉnh sửa bài viết của chính mình. Còn các member sẽ không có quyền truy cập vào trang admin. Để tìm hiểu thêm về cancancan bạn có thể tham khảo thêm tại đây và tại đây

Enumeration

Như ở trên, đối với trường role của user ta có 3 loại khác nhau. Và để rails_admin có thể hiển thị các lựa chọn dưới dạng một select box thay vì các text box mặc định, ta sẽ cần định nghĩa cho role_enum trong model User

  def role_enum
    ["super admin", "publisher", "member"]
  end

Trên đây mình đã tạo xong một trang admin demo đơn giản. Các bạn có thể tải về mã nguồn demo tại đây

Nguồn tham khảo

  • https://github.com/galetahub/ckeditor
  • https://github.com/CanCanCommunity/cancancan
  • https://github.com/sferik/rails_admin
  • https://github.com/sferik/rails_admin/wiki
0