session_attributes 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +58 -0
  3. data/Rakefile +3 -0
  4. data/lib/session_attributes.rb +134 -0
  5. metadata +77 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: feb87cc568ea512e11a933810d21649fa427f90902d17006aa87d4a1ebd2f8ea
4
+ data.tar.gz: 81a4bf5a3604b4ef10a613ba5c69141d70193ec368b53c9126d39adce1b6b83c
5
+ SHA512:
6
+ metadata.gz: da4f993c225cd016faeffd894a0c8bdc918eceae8d9431544c0608406985b50998d0b3b49ac2b5a27a9e100fd88568cb47e04254f42026ffe614375740066904
7
+ data.tar.gz: 110b9c7a5a5b5b84ecfde6a455df5b6676c795579098568bfa7b6e236b8d621fda15c8e53929fdaec1ec5a5a2311d572c1f14ac322576c5bbacec442c1e19668
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # SessionAttributes
2
+
3
+ A modified `ActiveSupport::CurrentAttributes` designed to persist across sessions. Useful for creating fancy singletons for storing session attributes
4
+
5
+ For more documentation, visit the `ActiveSupport::CurrentAttributes` docs [here](https://edgeapi.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html)
6
+
7
+ ## Usage
8
+
9
+ Create a class inheriting from `SessionAttributes` in app/models:
10
+
11
+ ```
12
+ class Journey < SessionAttributes
13
+ attribute :explorer, :basecamp
14
+ end
15
+ ```
16
+
17
+ Then utilize it in your controllers:
18
+
19
+ ```
20
+ Journey.explorer = Member.find(params[:username])
21
+ ```
22
+
23
+
24
+ ```
25
+ Journey.explorer.update!(name: "SessionAttributes Demo")
26
+ ```
27
+
28
+ ```
29
+ Journey.reset
30
+ ```
31
+
32
+ ## Installation
33
+
34
+ Add this line to your application's Gemfile:
35
+
36
+ ```ruby
37
+ gem "session_attributes"
38
+ ```
39
+
40
+ And then execute:
41
+
42
+ ```bash
43
+ $ bundle
44
+ ```
45
+
46
+ Or install it yourself as:
47
+
48
+ ```bash
49
+ $ gem install session_attributes
50
+ ```
51
+
52
+ ## Contributing
53
+
54
+ Contribution directions go here.
55
+
56
+ ## License
57
+
58
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require "bundler/setup"
2
+
3
+ require "bundler/gem_tasks"
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/callbacks"
4
+ require "active_support/core_ext/object/with"
5
+ require "active_support/core_ext/enumerable"
6
+ require "active_support/core_ext/module/delegation"
7
+ require "binding_of_caller"
8
+
9
+ class SessionAttributes
10
+ include ActiveSupport::Callbacks
11
+ define_callbacks :reset
12
+
13
+ INVALID_ATTRIBUTE_NAMES = [:set, :reset, :resets, :instance, :before_reset, :after_reset, :reset_all, :clear_all] # :nodoc:
14
+
15
+ class << self
16
+ def instance
17
+ new
18
+ end
19
+
20
+ def attribute(*names, default: nil)
21
+ invalid_attribute_names = names.map(&:to_sym) & INVALID_ATTRIBUTE_NAMES
22
+ if invalid_attribute_names.any?
23
+ raise ArgumentError, "Restricted attribute names: #{invalid_attribute_names.join(", ")}"
24
+ end
25
+
26
+ ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |owner|
27
+ names.each do |name|
28
+ owner.define_cached_method(name, namespace: :session_attributes) do |batch|
29
+ batch <<
30
+ "def #{name}" <<
31
+ "attributes[:#{name}]" <<
32
+ "end"
33
+ end
34
+ owner.define_cached_method("#{name}=", namespace: :session_attributes) do |batch|
35
+ batch <<
36
+ "def #{name}=(value)" <<
37
+ "attributes[:#{name}] = value" <<
38
+ "end"
39
+ end
40
+ end
41
+ end
42
+
43
+ ActiveSupport::Delegation.generate(singleton_class, names, to: :instance, nilable: false, signature: "")
44
+ ActiveSupport::Delegation.generate(singleton_class, names.map { |n| "#{n}=" }, to: :instance, nilable: false, signature: "value")
45
+
46
+ self.defaults = defaults.merge(names.index_with { default })
47
+ end
48
+
49
+ def before_reset(*methods, &)
50
+ set_callback(:reset, :before, *methods, &)
51
+ end
52
+
53
+ def resets(*methods, &)
54
+ set_callback(:reset, :after, *methods, &)
55
+ end
56
+ alias_method :after_reset, :resets
57
+
58
+ delegate :set, :reset, to: :instance
59
+
60
+ def reset_all # :nodoc:
61
+ session_instances.each_value(&:reset)
62
+ end
63
+
64
+ def clear_all # :nodoc:
65
+ reset_all
66
+ session_instances.clear
67
+ end
68
+
69
+ def attributes=(attrs)
70
+ session_instances[session_instances_key] ||= {}
71
+ session_instances[session_instances_key][:attributes] = attrs
72
+ end
73
+
74
+ def attributes
75
+ session_instances[session_instances_key] ||= {}
76
+ session_instances[session_instances_key][:attributes] ||= {}
77
+ end
78
+
79
+ private
80
+
81
+ def session_instances
82
+ i = 1
83
+ while !binding.of_caller(i).eval("(session rescue nil).is_a? ActionDispatch::Request::Session") && i < 50
84
+ i += 1
85
+ end
86
+ binding.of_caller(i).eval("session[:session_attributes_instances] ||= {}")
87
+ end
88
+
89
+ def generated_attribute_methods
90
+ @generated_attribute_methods ||= Module.new.tap { |mod| include mod }
91
+ end
92
+
93
+ def session_instances_key
94
+ @session_instances_key ||= name.to_sym
95
+ end
96
+
97
+ def method_added(name)
98
+ return if name == :initialize
99
+ return unless public_method_defined?(name)
100
+ return if respond_to?(name, true)
101
+ ActiveSupport::Delegation.generate(singleton_class, [name], to: :instance, as: self, nilable: false)
102
+ end
103
+ end
104
+
105
+ delegate :attributes, :attributes=, to: :class
106
+
107
+ def resolve_defaults
108
+ defaults.transform_values do |value|
109
+ (Proc === value) ? value.call : value.dup
110
+ end
111
+ end
112
+
113
+ # :nodoc:
114
+ # I had to move this to a self. method because it was erroring out with stack level too deep
115
+ def self.respond_to_missing?(name, _)
116
+ instance.respond_to?(name)
117
+ end
118
+
119
+ class_attribute :defaults, instance_writer: false, default: {}.freeze
120
+
121
+ def initialize
122
+ @attributes = resolve_defaults
123
+ end
124
+
125
+ def set(attributes, &)
126
+ with(**attributes, &)
127
+ end
128
+
129
+ def reset
130
+ run_callbacks :reset do
131
+ self.attributes = resolve_defaults
132
+ end
133
+ end
134
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: session_attributes
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Reese Armstrong
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-07-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 7.1.3.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 7.1.3.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: binding_of_caller
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ description: Store attributes in handy singletons for Rails/ActionDispatch sessions
42
+ email:
43
+ - me@reeseric.ci
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - README.md
49
+ - Rakefile
50
+ - lib/session_attributes.rb
51
+ homepage: https://codeberg.org/reesericci/session_attributes
52
+ licenses:
53
+ - MIT
54
+ metadata:
55
+ homepage_uri: https://codeberg.org/reesericci/session_attributes
56
+ source_code_uri: https://codeberg.org/reesericci/session_attributes
57
+ changelog_uri: https://codeberg.org/reesericci/session_attributes/releases
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubygems_version: 3.5.9
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: ActiveSupport::CurrentAttributes but for sessions
77
+ test_files: []