Shared posts

14 Mar 08:57

情色-日本寫真界熟女大PK 壇密只位居第二!!

by 大飛
本網站已依台灣網站內容分級規定處理,屬於成人網站含有情色內容,未滿18歲不得觀看


在日本競爭相當激烈的寫真界,
有不少靠著青春洋溢及好身材走紅的女星,
但其實有不少粉絲卻是獨愛「熟女」,
畢竟熟女所擁有的韻味,總是在少女身上找不到的,
這也讓幾位熟女女星,能在寫真界有著不錯的發展,
近期還特別做了熟女寫真女星的票選,
總共選出17位受到大多網友喜愛的熟女,
就讓各位也來看看榜單,是否也有符合自己口味的吧!!



17.向井悠 (31歲)



16.小松詩乃 (31歲)



16.森下悠里(31歲)



15.尾崎ナナ(33歲)



14.伊藤えみ(32歲)



13.相沢まき(35歲)



13.谷桃子(31歲)



12.吉見衣世(28歲)



11.手束真知子(30歲)



10.手島優(33歲)



09.小松彩夏(29歲)



08.磯山さやか(32歲)



07.木口亜矢(30歲)



06.戸田れい(29歲)



05.秋山莉奈(30歲)



04.川村ゆきえ(30歲)



03.杉原杏璃(33歲)



02.壇蜜(35歲)



01.橋本マナミ(31歲)



特別選出:山本梓(34歲)


其實這次上榜的好幾位熟女,
也都是我個人原本就滿愛的,
有幾位保養真的是相當的好,
根本完全感覺不出來他們已經超過30歲,
身材都還比一些年輕女星更加火辣,
難怪這些熟女能在寫真界佔有一席之位,
畢竟前天條件好,後天保養也是相當重要啊!!


圖片來源:網路翻攝

11 May 11:31

利用 cancan 实现一个优雅可扩展的角色管理系统

前言

我们在开发 web app 的时候, 非常常见的一个需求便是:

如何实现一个角色管理系统, 可以自由创建新角色, 每个角色可以关联许多资源( 权限 ), 并通过角色系统控制系统的访问权限.

本文即讲述 Rails 中如何优雅的, 以最少的代码量, 高可维护性来实现这个功能.

澄清权限管理的几个概念

用户管理系统: 很多新手将用户管理与权限管理混在一起, 实际上, 用户管理系统只解决一个问题: 用户如何被授权并登录系统的. 比如 密码认证, USB key 认证, Oauth2 认证等. 在 Rails 非常常用的 devise gem 正是解决这个问题的.

角色权限系统: 权限管理有很多种实现, 最为简单易用的即为基于角色的管理系统. 即:

资源: 被权限控制的对象称为资源, 一般新手会把权限跟资源混在一起, 这在实现系统的时候是大忌.

资源与控制器之间的关系: 资源与控制器是一对多的关系, 即每一个控制器的 action 可声明一个它使用的资源. 而资源, 则包括一个动作和一个对象(对应于 Rails 的 model ).

cancan 会有一个相对 "智能" 的方式自动加载并验证权限, 但我不建议使用, 因为它破坏了这种对应关系, 不仅声明了不必要的资源, 还过多使用了魔法来使得代码难于理解.

基本思路 - 站在巨人的肩上

Cancancan 是 Rails 界著名的权限管理系统, 以简单易用见长. 例如:

权限声明

class Ability
  include CanCan::Ability

  def initialize(user)
    if user.has_role?(:admin)
      can :create, User
    end
  end
end

权限控制:

<% if can? :update, @article %>
  <%= link_to "Edit", edit_article_path(@article) %>
<% end %>
def show
  @article = Article.find(params[:id])
  authorize! :read, @article
end

非常简单, 但唯一的问题就是, 它没有解决自定义角色与资源的问题, 必须写死 ability.rb 文件, 这叫我们很尴尬.

所以基本的思路是:

  1. 创建一套角色管理的 CRUD, 并引入 rolify gem 来帮我们管理角色与用户的关联( 忽略 rolify 对资源的管理, 个人以为它设计很差 )
  2. 引入新的一个 "表": resources, 称之为资源, 再引入另一个表: role_resources, 用来关联 roles 与 resources.
  3. 形成一个真正的可动态创建角色与资源的系统:

更优雅解决动态定义资源的问题

上述解决思路非常好, 但唯一有问题的是, 资源如果是数据库层创建的, 那该如何实现控制呢? 例如:

authorize! :read, @article

像这样的权限控制, 在数据库上如何存储字段.

还有更细粒的权限如何实现? 例如:

有一个商品订单, 有多个管理员, 要认领后才能操作, 也就是权限声明为:

can :close, Order do |order|
  order.allocated_by_admin == user
end

这个问题将 resources 存在数据库上就非常不方便. 我们反其道而行之:

  1. 资源几乎定义好不会变化
  2. 资源只会增, 不会减

这两个特点告诉我们, 我们完全可以像 cancan 那样做一个资源声明文件, 如下:

# 权限管理中的资源声明
class Resource
  include Resourcing
  group :order do

    resource :read, Order
    resource [ :approve, :decline, :freeze, :finish, :renew, :deposit_margin ], Order
  end

  group :staff do
    resource [ :read, :update, :destroy ], Staff do |admin, staff|
      # 总部的有更多的权限
      ( admin.branch_company_id.nil? or
        # 分部的必须相等
        admin.branch_company_id == staff.branch_company_id ) &&
          # 并且无法删除自己
          admin != staff
    end

    resource :create, Staff
  end

end

如此, 就可以非常优雅地定义与声明资源了, 并非常方便地集成在角色关联中. 那么主键是什么, 很明显, 资源的动作(verb)与数据对象(model)构成了唯一的键.

于是真正完整的数据表设计如下:

核心实现

如何实现存储 resources, 我们可使用 Rails 提供的 concerns :

# in file: app/models/concerns/resourcing.rb
module Resourcing
  extend ActiveSupport::Concern

  included do
    @groups = []
    @current_group = nil
    @resources = []
  end

  module ClassMethods

    # 为每个 resource 添加一个 group, 方便管理
    def group(name, &block)
      @groups << name
      @groups.uniq!
      @current_group = name
      block.call
    end

    def resource(verb_or_verbs, object, &block)
      raise "Need define group first" if @current_group.nil?
      group = @current_group
      behavior = block
      if verb_or_verbs.kind_of?(Array)
        verb_or_verbs.each do |verb|
          add_resource(group, verb, object, behavior)
        end
      else
        add_resource(group, verb_or_verbs, object, behavior)
      end
    end

    def add_resource(group, verb, object, behavior)
      name = "#{verb}_#{object.to_s.underscore}"
      resource = {
        name: name,
        group: group,
        verb: verb,
        object: object,
        behavior: behavior,
      }

      # TODO: check collision and uniqness here
      @resources << resource
    end

    def each_group(&block)
      @groups.each do |group|
        block.call(group)
      end
    end

    def each_resources_by(group, &block)
      resources = @resources.find_all { |r| r[:group] == group }
      resources.each(&block)
    end

    def find_by_name(name)
      resource = @resources.find { |r| r[:name] == name }
      raise "not found resource by name: #{name}" if resource.nil?
      resource
    end

  end
end

如何与 cancan 关联:

# in file: app/models/ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
    # Define abilities for the passed in user here. For example:
    #
    user ||= Staff.new # guest user (not logged in)

    if user.has_role?(:admin)
      can :manage, :all
    end

    # 去掉 admin role
    Role.all_without_reserved.each do |role|
      next unless user.has_role?(role.name)
      role.role_resources.each do |role_resource|
        resource = Resource.find_by_name(role_resource.resource_name)
        if resource[:behavior]
          block = resource[:behavior]
          can resource[:verb], resource[:object] do |object|
            block.call(user, object)
          end
        else
          can resource[:verb], resource[:object]
        end
      end
    end
  end
end

# in app/models/role.rb
# == Schema Information
#
# Table name: roles
#
#  id            :integer          not null, primary key
#  name          :string(255)
#  resource_id   :integer
#  resource_type :string(255)
#  created_at    :datetime
#  updated_at    :datetime
#

class Role < ActiveRecord::Base
  RESERVED = [ :admin, :guest ]
  has_and_belongs_to_many :staffs, :join_table => :staffs_roles

  has_many :role_resources, dependent: :destroy

  def self.all_without_reserved
    self.all.reject do |role|
      RESERVED.include?(role.name)
    end
  end

end
# in file: app/models/role_resource.rb
# == Schema Information
#
# Table name: role_resources
#
#  id            :integer          not null, primary key
#  role_id       :integer
#  resource_name :string(255)
#  created_at    :datetime
#  updated_at    :datetime
#

class RoleResource < ActiveRecord::Base
  validates_uniqueness_of :resource_name, scope: :role_id

  belongs_to :role
end

效果

通过以上的实现, 我们就可以得到像 cancan 一样易用的权限控制接口( 不变 ), 又可非常容易地定制 role 与 resource, 非常的酷.

例如:

role = Role.create(name: 'staff')
role.role_resources << RoleResource.create(resource_name: 'update_order')

user = User.first
user.add_role(role)
puts user.can?(:update, Order)
# output will be true

总结

可以自由创建角色的权限控制十分常见, 但如果想优雅地实现这个效果, 实际上难度非常大.

这一篇可以算是抛个砖, 实现了一个相对简单一些的需求.

如果你在做企业 ERP 类型的项目, 则还需要考虑 用户组资源组 的概念. 本文就不多说了.

也十分欢迎讨论相关主题.

22 Mar 15:16

By: dredow

by dredow

oo [57] xx [5]
22 Mar 15:16

By: BigChris梁非凡

by BigChris梁非凡

oo [54] xx [5]
22 Mar 15:12

By: 流浪炼金术士

by 流浪炼金术士





oo [13] xx [0]
17 Mar 08:37

[图]日本研发碳纤维无人机 韧性强抗冲击拍摄强

据日本媒体报道,近日,在日本仙台市举行的“联合国国际防灾会议”防灾产业展上,一款由该国东北大学开发、由碳纤维制骨架包裹的无人飞机正式亮相。据悉,在该无人机球型机体中,搭载有小型摄像机,当其在碰到障碍物之时,虽受到冲击会变弯,但仍可继续拍摄。此外,这款无人机直径仅为1米,机身轻便小巧,研究人员预计今后会将其应用在桥梁内侧的检查工作等领域。
09 Mar 18:02

By: 大姨胶布

by 大姨胶布

oo [39] xx [0]
09 Mar 17:53

By: i874

by i874

oo [37] xx [2]
09 Mar 17:51

By: qunheb

by qunheb

oo [40] xx [30]
09 Mar 17:51

By: 利爪卡蒙

by 利爪卡蒙

图大小不一,大家将就看了

oo [44] xx [0]
01 Dec 20:27

By: Asuka

by Asuka

多行不义必自毙

oo [13] xx [5]
01 Dec 20:21

By: honesty

by honesty

什么叫做有型

oo [49] xx [2]
01 Dec 20:21

By: lisen99

by lisen99

oo [67] xx [32]
01 Dec 20:15

By: honesty

by honesty

号称史上最悲伤的背打

oo [66] xx [7]
01 Dec 19:56

By: 换电池哥

by 换电池哥

oo [14] xx [0]
27 Nov 18:06

By: 换电池哥

by 换电池哥

200迈的赛车失控,老司机就是这么淡定

oo [40] xx [12]
27 Nov 18:06

By: 换电池哥

by 换电池哥

oo [23] xx [9]
03 Nov 13:31

By: 大杉刚

by 大杉刚

oo [56] xx [6]
23 Oct 06:27

By: 未正常过

by 未正常过

oo [58] xx [41]
23 Oct 06:04

By: G点在那里

by G点在那里

oo [20] xx [0]
23 Oct 05:59

By: moon

by moon

oo [120] xx [17]
23 Oct 05:59

By: M

by M

oo [101] xx [18]
23 Oct 05:38

By: kidd

by kidd

po主昨天在赛马比赛上拍到一只孩子丢失的,气球……

oo [29] xx [1]
22 Oct 10:17

By: B

by B

oo [81] xx [11]
22 Oct 10:14

By: glare

by glare

喵了个蛋的,这东西到底该怎么吃啊

oo [26] xx [1]
22 Oct 10:10

By: 一辉

by 一辉

如何哄一只猫睡觉

oo [82] xx [5]
13 Oct 16:10

By: blue

by blue

oo [29] xx [6]
13 Oct 16:06

By: Asuka

by Asuka

oo [141] xx [10]
13 Oct 16:06

By: 猫小路

by 猫小路

oo [36] xx [4]
13 Oct 16:04

By: Killl

by Killl

oo [68] xx [16]