session_attributes 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []