No release in over 3 years
Low commit activity in last 3 years
Support to attributes visible for each roles.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 2.0
~> 10.0
~> 3.0

Runtime

 Project Readme

ScopedAttributes

scoped_attributes provides a module that allows you to add access restriction settings to attributes. By using this, you can easily create a wrapper model that returns only the information required for each different role. I think it can also be used to API Scope and view models.

Installation

Add this line to your application's Gemfile:

gem 'scoped_attributes'

Usage

You can create a wrapper model by including the ScopedAttributes module.

class ApplicationScopedModel
  include ScopedAttributes
  roles :admin, :manager 

  def admin?
    user.admin?
  end

  def manager?
    user.manager?
  end
end
class ScopedCrew < ApplicationScopedModel
  attribute :id
  attribute :name
  attribute :address, only: proc { me? || admin? } # Proc
  attribute :evaluation, only: %i(admin) # role names (Array)

  def me?
    id == user.crew_id
  end
end

When using with ActiveRecord object

Specify the target object in the first argument and the user with the role in the second argument. The acquisition of the attribute is controlled by the condition specified in attribute class macro.

For an ActiveRecord object, you can use the to_model method to get the model instance with the attribute selected.

# current_user is not admin and not me
scoped_crew = ScopedCrew.new(Crew.find(1), current_user)
scoped_crew.name
# => "hoge"

scoped_crew.address
# => nil

scoped_crew.attributes
# => {:id=>1, :name=>"hoge"}

scoped_crew.to_model
# => #<Crew:xxx id: 1, name: "hoge">

Crew.find(1).scoped(current_user)
# => #<Crew:xxx id: 1, name: "hoge">
# current_user is not admin but is me
scoped_crew = ScopedCrew.new(Crew.find(1), current_user)
scoped_crew.name
# => "hoge"

scoped_crew.address
# => "tokyo"

scoped_crew.attributes
# => {:id=>1, :name=>"hoge", :address=>"tokyo"}

scoped_crew.to_model
# => #<Crew:xxx id: 1, name: "hoge", address: "tokyo">

Crew.find(1).scoped(current_user)
# => #<Crew:xxx id: 1, name: "hoge", address: "tokyo">
# current_user is admin
scoped_crew = ScopedCrew.new(Crew.find(1), current_user)
scoped_crew.name
# => "hoge"

scoped_crew.address
# => "tokyo"

scoped_crew.attributes
# => {:id=>1, :name=>"hoge", :address=>"tokyo", :evaluation=>"SS"}

scoped_crew.to_model
# => #<Crew:xxx id: 1, name: "hoge", address: "tokyo", evaluation: "SS">

Crew.find(1).scoped(current_user)
# => #<Crew:xxx id: 1, name: "hoge", address: "tokyo", evaluation: "SS">

When using with PORO

ScopedAttributes module can also be used by including it in PORO(Plain Old Ruby Object).

class ScopedCrew < ApplicationScopedModel
  attribute :name
  attribute :addres
  attribute :evaluation, only: %i(admin)
end

class CustomCrew
  attr_accessor :name, :address, :evaluation
  
  def initialize(name, address, evaluation)
    self.name = name
    self.address = address
    self.evaluation = evaluation
  end
end

crew = CustomCrew.new("hoge", "tokyo", "SS")
scoped_crew = ScopedCrew.new(crew, current_user)
scoped_crew.attributes
# => {:name=>"hoge", :address=>"tokyo"}

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/shunhikita/scoped_attributes.