scoped_attributes 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 78381184544a7b5f61b066c19d17878251f8ae47c575386c44ec72a616c16b85
4
+ data.tar.gz: f149b82115e1aa5cd9caf2dede0e23a6375aa2eb03a4b22935583cf0afb1606d
5
+ SHA512:
6
+ metadata.gz: '086dfa13d6c36dd9c6ce46de3fe2844ff91de2cbf00258dbbe51418159fbf65590ee66d5f70fd95a480a8c254148cac24c6171ef02eacb5c7da3b12cfc98cbb8'
7
+ data.tar.gz: d67ccd206353b78b1ec44ee1a01bca25fea3282da4a1c0a462823eee9e0a82b7c6f0efa89d8a3cb701d7b633060db2a52c0ddeddc3fd92d7d0bdce659925b0f0
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.6.5
7
+ before_install: gem install bundler -v 2.0.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in scoped_attributes.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,50 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ scoped_attributes (0.1.0)
5
+ activesupport (>= 5.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (6.0.2)
11
+ concurrent-ruby (~> 1.0, >= 1.0.2)
12
+ i18n (>= 0.7, < 2)
13
+ minitest (~> 5.1)
14
+ tzinfo (~> 1.1)
15
+ zeitwerk (~> 2.2)
16
+ concurrent-ruby (1.1.5)
17
+ diff-lcs (1.3)
18
+ i18n (1.7.0)
19
+ concurrent-ruby (~> 1.0)
20
+ minitest (5.13.0)
21
+ rake (10.5.0)
22
+ rspec (3.9.0)
23
+ rspec-core (~> 3.9.0)
24
+ rspec-expectations (~> 3.9.0)
25
+ rspec-mocks (~> 3.9.0)
26
+ rspec-core (3.9.0)
27
+ rspec-support (~> 3.9.0)
28
+ rspec-expectations (3.9.0)
29
+ diff-lcs (>= 1.2.0, < 2.0)
30
+ rspec-support (~> 3.9.0)
31
+ rspec-mocks (3.9.0)
32
+ diff-lcs (>= 1.2.0, < 2.0)
33
+ rspec-support (~> 3.9.0)
34
+ rspec-support (3.9.0)
35
+ thread_safe (0.3.6)
36
+ tzinfo (1.2.5)
37
+ thread_safe (~> 0.1)
38
+ zeitwerk (2.2.2)
39
+
40
+ PLATFORMS
41
+ ruby
42
+
43
+ DEPENDENCIES
44
+ bundler (~> 2.0)
45
+ rake (~> 10.0)
46
+ rspec (~> 3.0)
47
+ scoped_attributes!
48
+
49
+ BUNDLED WITH
50
+ 2.0.2
data/README.md ADDED
@@ -0,0 +1,148 @@
1
+ # ScopedAttributes
2
+
3
+ ## Installation
4
+
5
+ Add this line to your application's Gemfile:
6
+
7
+ ```ruby
8
+ gem 'scoped_attributes'
9
+ ```
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install scoped_attributes
18
+
19
+ ## Usage
20
+
21
+ create scoped class
22
+
23
+ ```rb
24
+ class ApplicationScopedModel
25
+ include ScopedAttributes
26
+ roles :admin, :crew
27
+
28
+ def admin?
29
+ user.admin?
30
+ end
31
+
32
+ def crew?
33
+ !admin?
34
+ end
35
+ end
36
+ ```
37
+
38
+ ```rb
39
+ class ScopedCrew < ApplicationScopedModel
40
+ attribute :id
41
+ attribute :name
42
+ attribute :address, only: proc { me? || admin? } # Proc
43
+ attribute :evaluation, only: %i(admin) # role names (Array)
44
+
45
+ def me?
46
+ id == user.crew_id
47
+ end
48
+ end
49
+ ```
50
+
51
+ ### for ActiveRecord
52
+
53
+ usage
54
+
55
+ current_user is crew and crew is not me
56
+
57
+ ```rb
58
+ scoped_crew = ScopedCrew.new(Crew.find(1), current_user)
59
+ scoped_crew.name
60
+ # => "hoge"
61
+
62
+ scoped_crew.address
63
+ # => nil
64
+
65
+ scoped_crew.attributes
66
+ # => {:id=>1, :name=>"hoge"}
67
+
68
+ scoped_crew.to_model
69
+ => #<Crew:xxx id: 1, name: "hoge">
70
+
71
+ Crew.find(1).scoped
72
+ => #<Crew:xxx id: 1, name: "hoge">
73
+ ```
74
+
75
+ current_user is crew and crew is me
76
+ ```rb
77
+ scoped_crew = ScopedCrew.new(Crew.find(1), current_user)
78
+ scoped_crew.name
79
+ # => "hoge"
80
+
81
+ scoped_crew.address
82
+ # => "tokyo"
83
+
84
+ scoped_crew.attributes
85
+ # => {:id=>1, :name=>"hoge", :address=>"tokyo"}
86
+
87
+ scoped_crew.to_model
88
+ => #<Crew:xxx id: 1, name: "hoge", address: "tokyo">
89
+
90
+ Crew.find(1).scoped
91
+ => #<Crew:xxx id: 1, name: "hoge", address: "tokyo">
92
+ ```
93
+
94
+ current_user is admin
95
+
96
+ ```rb
97
+ scoped_crew = ScopedCrew.new(Crew.find(1), current_user)
98
+ scoped_crew.name
99
+ # => "hoge"
100
+
101
+ scoped_crew.address
102
+ # => "tokyo"
103
+
104
+ scoped_crew.attributes
105
+ # => {:id=>1, :name=>"hoge", :address=>"tokyo", :evaluation=>"SS"}
106
+
107
+ scoped_crew.to_model
108
+ => #<Crew:xxx id: 1, name: "hoge", address: "tokyo", evaluation: "SS">
109
+
110
+ Crew.find(1).scoped
111
+ => #<Crew:xxx id: 1, name: "hoge", address: "tokyo", evaluation: "SS">
112
+ ```
113
+
114
+ ## for pure object
115
+
116
+ ```rb
117
+ class ScopedCrew < ApplicationScopedModel
118
+ attribute :name
119
+ attribute :addres
120
+ attribute :evaluation, only: %i(admin)
121
+ end
122
+
123
+ class CustomCrew
124
+ attr_accessor :name, :address, :evaluation
125
+
126
+ def initialize(name, address, evaluation)
127
+ self.name = name
128
+ self.address = address
129
+ self.evaluation = evaluation
130
+ end
131
+ end
132
+
133
+ crew = CustomCrew.new("hoge", "tokyo", "SS")
134
+ scoped_crew = ScopedCrew.new(crew, current_user)
135
+ scoped_crew.attributes
136
+ # => {:name=>"hoge", :address=>"tokyo"}
137
+ ```
138
+
139
+
140
+ ## Development
141
+
142
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
143
+
144
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
145
+
146
+ ## Contributing
147
+
148
+ Bug reports and pull requests are welcome on GitHub at https://github.com/shunhikita/scoped_attributes.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "scoped_attributes"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,15 @@
1
+ require 'rails/railtie'
2
+
3
+ module ScopedAttributes
4
+ class Railtie < Rails::Railtie
5
+ initializer 'scoped_attributes.setup_orm' do
6
+ [:active_record].each do |orm|
7
+ ActiveSupport.on_load orm do
8
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
9
+ include ScopedAttributes::Scopable
10
+ RUBY
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ module ScopedAttributes
2
+ module Scopable
3
+ extend ActiveSupport::Concern
4
+
5
+ def scoped(user)
6
+ klass_name = "Scoped#{self.model_name}"
7
+ klass_name.constantize.new(self, user).to_model
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module ScopedAttributes
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,111 @@
1
+ require "scoped_attributes/version"
2
+ require "scoped_attributes/scopable"
3
+ require 'scoped_attributes/railtie' if defined?(Rails)
4
+ require "active_support/concern"
5
+
6
+ module ScopedAttributes
7
+ extend ActiveSupport::Concern
8
+ class Error < StandardError; end
9
+
10
+ def initialize(object, user)
11
+ self.object = object
12
+ self.user = user
13
+ end
14
+
15
+ included do
16
+ class_attribute :attributes_registry, instance_accessor: false
17
+ class_attribute :model_name, instance_accessor: true
18
+ self.attributes_registry = {}
19
+
20
+ attr_accessor :object, :user
21
+ end
22
+
23
+ class_methods do
24
+ def roles(*role_names)
25
+ role_names.each do |role_name|
26
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
27
+ def #{role_name}?
28
+ raise NotImplementedError.new("You must implement #{self.class}##{__method__}")
29
+ end
30
+ RUBY
31
+ end
32
+ end
33
+
34
+ def attribute(name, **options)
35
+ add_attribute_registry(name.to_sym, options)
36
+ define_attribute_reader(name.to_sym, options)
37
+ end
38
+
39
+ def add_attribute_registry(name, options)
40
+ self.attributes_registry.merge!(name => options)
41
+ end
42
+
43
+ def define_attribute_reader(name, options)
44
+ only = options.fetch(:only, nil)
45
+
46
+ define_method name do
47
+ object.public_send(name) if visible?(only)
48
+ end
49
+ end
50
+ end
51
+
52
+ def model
53
+ (self.class.model_name || self.class.name.gsub("Scoped", "")).safe_constantize
54
+ end
55
+
56
+ def as_json
57
+ attributes
58
+ end
59
+
60
+ def to_model
61
+ return nil if model.nil?
62
+
63
+ if object&.id.nil?
64
+ model.new(attributes)
65
+ else
66
+ model.select(attributes.keys).find_by(id: object.id)
67
+ end
68
+ end
69
+
70
+ def attributes(include_key: false)
71
+ attributes = {}
72
+ self.class.attributes_registry.each do |name, options|
73
+ only = options.fetch(:only, nil)
74
+
75
+ if visible?(only)
76
+ attributes[name] = object.public_send(name)
77
+ elsif include_key
78
+ attributes[name] = nil
79
+ end
80
+ end
81
+ attributes
82
+ end
83
+
84
+ private
85
+
86
+ def visible?(only)
87
+ return true if only.nil?
88
+
89
+ case only
90
+ when Array
91
+ only.any? { |role| public_send("#{role}?") }
92
+ when String
93
+ only.public_send(string)
94
+ when Proc
95
+ unbound_method = generate_method(:only_call, &only)
96
+ !!unbound_method.bind(self).call
97
+ else
98
+ false
99
+ end
100
+ end
101
+
102
+ def generate_method(method_name, &block)
103
+ method = nil
104
+ Module.new do
105
+ define_method method_name, &block
106
+ method = instance_method method_name
107
+ remove_method method_name
108
+ end
109
+ method
110
+ end
111
+ end
@@ -0,0 +1,28 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "scoped_attributes/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "scoped_attributes"
7
+ spec.version = ScopedAttributes::VERSION
8
+ spec.authors = ["h1kita"]
9
+
10
+ spec.summary = "Support to attributes visible for each roles."
11
+ spec.description = "Support to attributes visible for each roles."
12
+
13
+ spec.metadata["source_code_uri"] = "https://github.com/shunhikita/scoped_attributes"
14
+
15
+ # Specify which files should be added to the gem when it is released.
16
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
17
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
18
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 2.0"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+ spec.add_dependency "activesupport", ">= 5.0"
28
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: scoped_attributes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - h1kita
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-12-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '5.0'
69
+ description: Support to attributes visible for each roles.
70
+ email:
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - ".gitignore"
76
+ - ".rspec"
77
+ - ".travis.yml"
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ - README.md
81
+ - Rakefile
82
+ - bin/console
83
+ - bin/setup
84
+ - lib/scoped_attributes.rb
85
+ - lib/scoped_attributes/railtie.rb
86
+ - lib/scoped_attributes/scopable.rb
87
+ - lib/scoped_attributes/version.rb
88
+ - scoped_attributes.gemspec
89
+ homepage:
90
+ licenses: []
91
+ metadata:
92
+ source_code_uri: https://github.com/shunhikita/scoped_attributes
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubygems_version: 3.0.3
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Support to attributes visible for each roles.
112
+ test_files: []