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基础汇总

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