ruby語言斷斷續續的編程筆記分享

斷斷續續繼續了一些ruby編程的筆記,都是一些很繼續的東西,在簡書這裏彙總一下。

一:如何使用Pundit進行權限管理

1.1:pundit介紹

有名的權限管理gem:
1.pundit:流行的權限管理(推薦,pundit更加適合大型項目,更加複雜的權限系統)
2.authority: 已經不維護了
3.cancancan: 比較老牌的權限管理的gem

作用:針對不同的用戶執行不同的操作(不同的用戶有不同的角色管理)
注意:用戶級別的角色管理,pundit是不包含這個功能的,角色的管理需要我們自己來設計和實現
pundit這個gem是需要根據我們自己所需要的邏輯,比如哪樣的用戶能夠幹什麼事情,說白了就是哪些用戶
能夠執行這個action,哪些用戶可以執行特定的邏輯操作,總得來說,pundit主要是做後端的一個權限管理的一個gem.

1.2:Pundit安裝和配置

1.在Gemfile中引入:

gem 'pundit'
bundle install

3.在app/controller/application_controller.rb中引入pundit這個模塊

include Pundit

說明:引入pundit這個模塊之後,我們就可以在controller和view中使用對應的方法來判斷對應的權限了
4.運行pundit初始化命令

rails g pundit:install

說明:運行完這條命令之後會生成app/policies/application_policy.rb這個文件
5.在config/application.rb加入下面的語句,讓其能自動加載

config.autoload_paths += %W[#{config.root}/app/policies]

1.3:Pundit的使用

這裏首先要明確幾點:

  • pundit策略的設置都是純根據ruby的類來實現的
  • 一個方法,比如index?是否返回true和false,是我們能夠使用app/policies/application_policy.rb這個文件裏user、record兩個變量來判斷當前的action是否返回true和false
  • policy設計的思路,每一個policy文件都是和模型對應的。比如傳過來的是一個post這個record,pundit就會查找app/policies/下是否有PostPolicy這個類,然後調用這個類的同名的這個方法,進而判斷權限,pundit和rails相似,有預先的約定和猜測。

舉個例子:
只有這個用戶發表的文章,他纔有刪改的權限
1)運行命令

rails g controller posts index show

在posts這個表創建個title這個列就行
2)在app/model/user.rb

class User < ApplicationRecord
  has_many :user
end

app/model/post.rb

class Post < ApplicationRecord
  belongs_to :user
end

3)在rails c中創建下測試數據

user = User.first
user.posts.create title: "Post 1"
user.posts.create title: "Post 2"
user2 = User.last
user.posts.create title: "Post 3"
user.posts.create title: "Post 4"

4)在app/controllers/posts_controller.rb中增加簡單的邏輯

class PostsController < ApplicationController
  
  def index
    @posts = Post.includes(:user)
  end

  def show
    @post = Post.find params[:id]
  end

  def edit
    @post = Post.find params[:id]
    authorize @post  #authorize是include Pundit提供的
  end

end

5)在config/routes.rb增加對應的路由

resources :posts

6)view層
app/views/posts/index.html.erb

<h1>Posts</h1>

<ul class="list-group">
  <% @posts.each do |post| %>
    <li class="list-group-item">
      <%= link_to post.title, post_path(post) %>,
      ID: <%= post.id %>,
      作者: <%= post.user.email %>
      <% if policy(post).edit? %>
        <%= link_to "編輯", edit_post_path(post), class: "btn btn-primary" %>
      <% end %>
    </li>
  <% end %>
</ul>

app/views/posts/show.html.erb

<h1>Posts</h1>

<h2><%= @post.title %></h2>
<p>作者: <%= @post.user.email %></p>

app/views/posts/edit.html.erb

<h1>Posts</h1>

<h2>編輯:<%= @post.title %></h2>

7)app/policies/policy.rb

class PostPolicy < ApplicationPolicy

  def edit?
    user.has_role?('admin') || user == record.user
  end

  def can_edit?
    true
  end

end

說明:會識別PostPolicy這個類,ApplicationPolicy有個user屬性,指的是current_user,ApplicationPolicy在實例化的時候,會初始化這個屬性

二:log4R配置

1.在config目錄下,創建一個log4r的配置文件: config/log4r.yml,內容編輯如下

log4r_config:  
  # define all loggers ...  
  loggers:  
    - name      : production  
      level     : WARN  
      trace     : 'false'  
      outputters :  
      - datefile  
    - name      : development  
      level     : DEBUG  
      trace     : 'true'  
      outputters :  
      - datefile  
  
  # define all outputters (incl. formatters)  
  outputters:  
  - type: DateFileOutputter  
    name: datefile  
    dirname: "log"  
    filename: "my_app.log" # notice the file extension is needed!  
    formatter:  
      date_pattern: '%H:%M:%S'  
      pattern     : '%d %l: %m '  
      type        : PatternFormatter  

2.修改config/application.rb文件如下

require 'rails/all'  
# add these line for log4r  
require 'log4r'  
require 'log4r/yamlconfigurator'  
require 'log4r/outputter/datefileoutputter'  
include Log4r  
  
Bundler.require(:default, Rails.env) if defined?(Bundler)  
module Zurich  
  class Application < Rails::Application  
    #...  
    # assign log4r's logger as rails' logger.  
    log4r_config= YAML.load_file(File.join(File.dirname(__FILE__),"log4r.yml"))  
    YamlConfigurator.decode_yaml( log4r_config['log4r_config'] )  
    config.logger = Log4r::Logger[Rails.env]  
  end  
end  

3.修改gemfile文件,增加log4r這個gem

gem 'log4r', '1.1.9'

這時候重啓rails,就會發現log目錄,會根據日期創建相應的log目錄了。

三:後臺框架-activeadmin

activeadmin code:https://github.com/activeadmin/activeadmin

官網:https://activeadmin.info/

gemfile:

gem 'activeadmin'

# Plus integrations with:
gem 'devise'
gem 'cancan' # or cancancan
gem 'draper'
gem 'pundit'

bundle install

3.1 set-up activeadmin

如果你不想使用devise

rails g active_admin:install --skip-users

如果想用已經存在的User

rails g active_admin:install User

other

rails g active_admin:install

會生成這些文件

app/admin/dashboard.rb
app/assets/javascripts/active_admin.js
app/assets/stylesheets/active_admin.scss
config/initializers/active_admin.rb

然後依次執行一下命令

rake db:migrate
rake db:seed
rails server

這些在官網安裝指南介紹的都很詳細,這裏列出我在實際項目中會用到的一些功能。
這裏也可以嘗試一下實際效果

3.2 自定義action

ActiveAdmin.register User do
  index do
    actions do |u|
      link_to('獲取用戶下級所有姓名', "/admin/users/#{u.id}/get_names", method: 'get')
    end
  end
end
member_action :get_names, :method => :get do
  #處理業務邏輯,這裏get請求,接收params[:id]參數
  render json: your_json_info
end

3.3 scope、filter、selectable_column、

1.scope:列表上面進行對列表中數據進行篩選,在model有需要有專門的方法存在。

2.filter:filter默認會過濾所有model的數據,這裏如果指定,將會覆蓋原本默認存在的。

3.4 index

1.selectable_column:在列表左方增加可以選擇的按鈕,這裏一般是爲了可以進行批量刪除/處理操作。
2.id_column:顯示字段的id字段。
3.如果不定義index是默認顯示全部。跟filter一個道理,這裏定義column可以根據實際需要顯示需要展示的列。

3.5 form

1.用input來定義需要添加/修改的列
如果需要將某幾個字段放在一起,然後用指定的名字定義下面的字段,可以這樣寫:

form do |_|
  inputs '這裏展示區域_a' do
    column: a_1
    column: a_2
  end
end

另外input中針對於特殊字段,可以顯示出特定的格式:
1.1 日期:

input :push_start_time, as: :datepicker, label: '開始時間' #這裏顯示的是yyyy-mm-dd
input :push_start_time, as: :date_picker, label: '開始時間' #這裏顯示的是yyyy-mm-dd mm:dd::ss

1.2 下拉:

input :order_info, as: :select, collection: [['有訂單', true], ['無訂單', false]], label: '適用人羣', selected: '有訂單' #下拉按鈕,這裏可以設置選中哪一個

1.3 上傳:

input cover as: file, label: "封面", hint: "233x292"

1.4 單選:

input :plans, as: :check_boxes,
              label: '人員限制',
              collection: [:user_a, :user_b],
              selected: :user_a #注意,這是是symbol

這裏有一個值得注意的點,我發現每次保存的時候,都無法將plans保存到數據庫中,我在permit_params也寫入了plans,對了在admin/你的model.rb中需要寫入permit_params,這裏是允許哪些字段,這就是rails的健壯參數了,這裏不多做概述,迴歸整體,這裏針對於plans不能寫

permit_params :plans 

因爲plans是check_boxes,這裏需要指定格式

permit_params plans: []

這樣就好了

3.6 other

1.還有一種情況,你可能在設計表的時候,可能採用一個列中存在多個字段的情況,這就需要在model進行序列化的操作,那在activeadmin中如果展示出來呢

看下面的兩個文檔,或許能解決你的問題:

JSON Serialized Columns with Rails

Dealing with JSON data in Active Admin

2.針對於notice flash消息不能正常顯示的問題

Add flash messages for actions

四:rails中的reject和merge方法

在進行rails開發的時候,針對於hash最常用的方法是reject和hash的方法

4.1 reject方法

1)reject方法和描述
hash.reject { |key, value| block }
類似 delete_if, 但作用在一個拷貝的哈希上。相等於 hsh.dup.delete_if。

2)reject!方法和描述
hash.reject! { |key, value| block }
相等於 delete_if, 但是如果沒有修改,返回 nil。

2.3.3 :001 > h = {:a => 1, :b => 2}
 => {:a=>1, :b=>2}
2.3.3 :002 > h.delete(:a)
 => 1
2.3.3 :003 > h
 => {:b=>2}
2.3.3 :004 > h = {:a => 1, :b => 2}
 => {:a=>1, :b=>2}
2.3.3 :005 > h.delete_if {|k,v| v != 3}
 => {}
2.3.3 :006 > h
 => {}
2.3.3 :007 > h = {:a => 1, :b => 2}
 => {:a=>1, :b=>2}
2.3.3 :008 > h.reject{|k, v| v!=2}
 => {:b=>2}
2.3.3 :009 > h
 => {:a=>1, :b=>2}
2.3.3 :010 > h = {:a => 1, :b => 2}
 => {:a=>1, :b=>2}
2.3.3 :011 > h.reject!{|k, v| v!=2}
 => {:b=>2}
2.3.3 :012 > h
 => {:b=>2}
 2.3.3 :015 > h = {:a => 1, :b => 2}
 => {:a=>1, :b=>2}
2.3.3 :016 > h.reject{|k, v| v!=2}
 => {:b=>2}
2.3.3 :017 > h
 => {:a=>1, :b=>2}
2.3.3 :018 > h.reject!{|k, v| v!=2}
 => {:b=>2}
2.3.3 :019 > h
 => {:b=>2}
2.3.3 :020 > h.reject!{|k, v| v!=2}
 => nil

4.2 merge方法

1)merge方法和描述

hash.merge(other_hash) [or]
hash.merge(other_hash) { |key, oldval, newval| block }

2)merge!方法和描述

hash.merge!(other_hash) [or]
hash.merge!(other_hash) { |key, oldval, newval| block }
與 merge 相同,但實際上 hash 發生了變化。

other

更基礎的東西,請看這篇ruby基礎彙總

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章