lazy_record 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1dd02d425756e1e782fb8ddb8200ebd979d8b46d
4
- data.tar.gz: 8033557b1ed171bacc267b69402f59122f496ee6
3
+ metadata.gz: ecdcea0a9c3288387372a9251debe33d83372906
4
+ data.tar.gz: a0fd6848c4ab36434e5ecb4c88dac81f851bb708
5
5
  SHA512:
6
- metadata.gz: 5e9680e081c05fef1268a6b6ec662634bce7ba75eff2d5db8518bbe9eaa36152b28f4bb66fffa44ab03d11897f35ada16d1abf59377a58fd72ddfdb50a32fb85
7
- data.tar.gz: 2de4c3dd15b30c3540e1f01142c5c03155af15720ecd83aa4ee828e8228c567c3b19903e94611d9e4e8d18f02efb32b89eb88ed5d622caae6d62a7d07b6de32f
6
+ metadata.gz: aa77719da043990d92bd9dc2aaf5dbef32f125dedac67247cc385f68ee846121a6206fe067d07d335c0f465967f04024e3a3486a067b565ed7f521f57375c71d
7
+ data.tar.gz: f64d912e5021fb72ad64e0370ae7edae5c60e42ef17582953ca27c65e718b3383c75962b357cc08f79a5e64cc614d23710bf1bff0b97e82e7527b343008faa13
data/README.md CHANGED
@@ -45,24 +45,50 @@ thing = Thing.new { |t| puts t.class.superclass }
45
45
  ```
46
46
  Every LazyRecord object is assigned an auto-incrementing ID after initialization. IDs reset when the program is terminated.
47
47
 
48
- Use `lr_attr_accessor` like you would use `attr_accessor`. You'll get hash syntax in your `#intialize` method for attribute setting.
48
+ Use `attr_accessor` like you would use normally, and you'll get hash syntax in your `#intialize` method for attribute setting. The attributes will also be visible when the object is returned or `inspected`. Attributes defined with `attr_reader` will also be visible, but `attr_writers`, custom getters and writers, and other methods will not.
49
49
 
50
50
  ```ruby
51
51
  class Thing < LazyRecord::Base
52
- lr_attr_accessor :stuff, :junk
52
+ attr_accessor :stuff, :junk
53
+ attr_reader :hmm
54
+
55
+ def something
56
+ @something ||= 'something'
57
+ end
53
58
  end
54
59
 
55
60
  thing = Thing.new stuff: 'stuff' do |t|
56
61
  t.junk = 'junk'
57
62
  end
58
- # => #<Thing id: 1, stuff: "stuff", junk: "junk">
63
+ # => #<Thing id: 1, stuff: "stuff", junk: "junk", hmm: nil>
64
+ thing.something
65
+ # => "something"
66
+ ```
67
+ If you want to define private or protected `attr_accessor`s or `attr_reader`s, they will not be visible when inspecting the object, and you should do so like the following example.
68
+ ```ruby
69
+ class Thing < LazyRecord::Base
70
+ attr_accessor :stuff, :junk
71
+ private :junk, :junk= # passing the setter and getter method names as arguments to Module.private/Module.protected will work
72
+
73
+ private_attr_accessor :hmm # this also works
74
+ protected_attr_accessor :huh # this works too
75
+
76
+ private
77
+ attr_accessor :what # declaring the methods after calling the private method will not work, and the methods will be public and visible.
78
+ # this is a bug due to the custom implementation of .attr_*, and if anyone can find a fix please submit it!
79
+ # otherwise, the other two forms work just fine.
80
+ # and really, who wants to declare private attr_accessors this way anyway :-P ?
81
+ end
59
82
  ```
83
+ Earlier implementations used a custom `lr_attr_accessor` method, however this has been deprecated in favor of overriding `attr_*` so the methods will be parsed by RDoc.
84
+
85
+ See @dbrady's `scoped_attr_accessor` gem for more info on the `scoped_attr_*` methods.
60
86
 
61
87
  Validate presence of attributes with `lr_validates` like you would with ActiveRecord. Failed validations will return false and the ID will not be incremented. More validation options coming in the future.
62
88
 
63
89
  ```ruby
64
90
  class Thing < LazyRecord::Base
65
- lr_attr_accessor :stuff, :junk
91
+ attr_accessor :stuff, :junk
66
92
  lr_validates :stuff, presence: true
67
93
  end
68
94
 
@@ -79,7 +105,7 @@ class Whatever < LazyRecord::Base
79
105
  end
80
106
 
81
107
  class Thing < LazyRecord::Base
82
- lr_attr_accessor :stuff, :junk
108
+ attr_accessor :stuff, :junk
83
109
  lr_validates :stuff, presence: true
84
110
  lr_has_many :whatevers
85
111
  end
@@ -101,7 +127,7 @@ Use `lr_scope` and `#where` to create class scope methods and query objects. Wor
101
127
 
102
128
  ```ruby
103
129
  class Whatever < LazyRecord::Base
104
- lr_attr_accessor :party_value, :sleepy_value
130
+ attr_accessor :party_value, :sleepy_value
105
131
  lr_scope :big_party, -> { where('party_value > 10') }
106
132
  lr_scope :low_sleepy, -> { where('sleepy_value < 10') }
107
133
  end
@@ -158,13 +184,13 @@ Use `lr_method` for an alternative API for defining short instance methods. Can
158
184
 
159
185
  ```ruby
160
186
  class Whatever < LazyRecord::Base
161
- lr_attr_accessor :party_value, :sleepy_value, :right
187
+ attr_accessor :party_value, :sleepy_value, :right
162
188
  lr_scope :big_party, -> { where('party_value > 10') }
163
189
  lr_scope :low_sleepy, -> { where('sleepy_value < 10') }
164
190
  end
165
191
 
166
192
  class Thing < LazyRecord::Base
167
- lr_attr_accessor :stuff, :junk
193
+ attr_accessor :stuff, :junk
168
194
  lr_validates :stuff, presence: true
169
195
  lr_has_many :whatevers
170
196
  lr_method :speak, -> (string) { puts string }
data/lazy_record.gemspec CHANGED
@@ -16,8 +16,6 @@ Gem::Specification.new do |spec|
16
16
  spec.license = 'MIT'
17
17
  spec.required_ruby_version = '>= 2.1.0'
18
18
 
19
- # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
20
- # to allow pushing to a single host or delete this section to allow pushing to any host.
21
19
  if spec.respond_to?(:metadata)
22
20
  spec.metadata['allowed_push_host'] = 'https://rubygems.org'
23
21
  else
@@ -32,7 +30,8 @@ Gem::Specification.new do |spec|
32
30
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
33
31
  spec.require_paths = ['lib']
34
32
 
35
- spec.add_dependency 'activesupport'
33
+ spec.add_dependency 'activesupport', '~> 5.0'
34
+ spec.add_dependency 'scoped_attr_accessor', '~> 1.0', '>= 1.0.3'
36
35
 
37
36
  spec.add_development_dependency 'pry'
38
37
  spec.add_development_dependency 'rspec'
data/lib/lazy_record.rb CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'active_support'
4
4
  require 'active_support/inflector'
5
+ require 'scoped_attr_accessor'
6
+
5
7
  require 'lazy_record/version'
6
8
  require 'lazy_record/associations'
7
9
  require 'lazy_record/attributes'
@@ -92,18 +92,18 @@ module LazyRecord
92
92
  end
93
93
 
94
94
  def define_has_one_associations_to_s
95
- define_method(:has_one_associations_to_s) do
95
+ define_method(:associations_to_s) do
96
96
  associations.map do |association|
97
97
  "#{association}: #{stringify_value(send(association))}"
98
98
  end
99
99
  end
100
- private :has_one_associations_to_s
100
+ private :associations_to_s
101
101
  end
102
102
 
103
- def define_association_setter(association)
104
- model = find_scoped_association_class(association)
105
- define_method("#{association}=") do |assoc|
106
- return instance_variable_set("@#{association}", assoc) if assoc.is_a? model.call
103
+ def define_association_setter(assoc)
104
+ model = find_scoped_association_class(assoc)
105
+ define_method("#{assoc}=") do |value|
106
+ return instance_variable_set("@#{assoc}", value) if value.is_a? model.call
107
107
  raise ArgumentError, "Argument must be a #{model.call}"
108
108
  end
109
109
  end
@@ -7,42 +7,28 @@ module LazyRecord
7
7
  # yields self to a block. If you want to add custom functionality to
8
8
  # #initialize just call super.
9
9
  module Attributes
10
- ATTR_MODULE_NAME = :DynamicAttributes
11
-
12
- def define_setters_and_getters(name)
13
- define_method(name) do
14
- instance_variable_get('@' + name.to_s)
15
- end
16
-
17
- define_method("#{name}=") do |val|
18
- instance_variable_set('@' + name.to_s, val)
19
- end
10
+ def lr_attr_accessor(*names) # TODO: remove in version 1.0.0
11
+ puts 'Using `.lr_attr_accessor` is deprecated. Use the standard `.attr_*`'\
12
+ ' methods instead. You will get the same results, plus the methods will be'\
13
+ ' recognized by rdoc. `.lr_attr_accessor` will be removed in version 1.0.0'
14
+ attr_accessor(*names)
20
15
  end
21
16
 
22
- def define_instance_attrs_to_s
23
- define_method(:instance_attrs_to_s) do
24
- instance_attr_accessors.map do |attr|
25
- value = send(attr)
26
- "#{attr}: #{stringify_value(value)}"
27
- end
28
- end
29
- private :instance_attrs_to_s
17
+ undef_method(:lr_attr_accessor) if LazyRecord::VERSION >= '1.0.0'
18
+
19
+ def attr_accessor(*names)
20
+ super(*names)
21
+ add_to_attr_readers(*names)
30
22
  end
31
23
 
32
- def define_instance_attr_accessors(*names)
33
- define_method(:instance_attr_accessors) do
34
- names.map(&:to_sym)
35
- end
36
- private :instance_attr_accessors
24
+ def attr_reader(*names)
25
+ super(*names)
26
+ add_to_attr_readers(*names)
37
27
  end
38
28
 
39
- def lr_attr_accessor(*names)
40
- include mod = get_or_set_mod(ATTR_MODULE_NAME)
41
- mod.extend(Attributes)
42
- mod.module_eval do
43
- names.each { |name| define_setters_and_getters(name) }
44
- define_instance_attr_accessors(*names)
45
- define_instance_attrs_to_s
29
+ def add_to_attr_readers(*names)
30
+ names.each do |name|
31
+ attr_readers << name.to_sym
46
32
  end
47
33
  end
48
34
  end
@@ -4,7 +4,9 @@ module LazyRecord
4
4
  # This module gives the Base class its functionality, and can be included
5
5
  # in any class as an alternative to inheriting from LazyRecord::Base
6
6
  module BaseModule
7
+ # Extend these modules when BaseModule is included
7
8
  def self.included(base)
9
+ base.extend ScopedAttrAccessor
8
10
  base.extend ClassMethods
9
11
  base.extend Scopes
10
12
  base.extend Attributes
@@ -17,34 +19,42 @@ module LazyRecord
17
19
 
18
20
  attr_writer :id
19
21
 
22
+ # Use options hash to set attributes, and/or operate on object in a block.
23
+ # Checks each options key for a matching attribute setter method.
20
24
  def initialize(opts = {})
21
- opts.each do |k, v|
22
- send("#{k}=", v) if respond_to?("#{k}=")
25
+ opts.each do |key, val|
26
+ send("#{key}=", val) if respond_to?("#{key}=")
23
27
  end
24
28
  yield self if block_given?
25
29
  end
26
30
 
27
- def instance_attrs_to_s
31
+ def collection_counts_to_s
28
32
  []
29
33
  end
30
34
 
31
- def instance_attr_accessors
32
- []
35
+ def public_attr_readers_to_s
36
+ @public_attr_readers_to_s ||=
37
+ self.class.send(:public_attr_readers).map do |attr|
38
+ value = send(attr)
39
+ "#{attr}: #{stringify_value(value)}"
40
+ end
33
41
  end
34
42
 
35
- def collection_counts_to_s
43
+ def associations_to_s
36
44
  []
37
45
  end
38
46
 
39
- def has_one_associations_to_s
40
- []
47
+ def inspect
48
+ format('#<%s id: %s%s%s%s>',
49
+ self.class,
50
+ display_id_even_if_nil,
51
+ public_attr_readers_to_s.dup.unshift('').join(', '),
52
+ associations_to_s.unshift('').join(', '),
53
+ collection_counts_to_s.unshift('').join(', '))
41
54
  end
42
55
 
43
- def inspect
44
- "#<#{self.class} id: #{id ? id : 'nil'}"\
45
- "#{instance_attrs_to_s.unshift('').join(', ')}"\
46
- "#{has_one_associations_to_s.unshift('').join(', ')}"\
47
- "#{collection_counts_to_s.unshift('').join(', ')}>"
56
+ def display_id_even_if_nil
57
+ id ? id.to_s : 'nil'
48
58
  end
49
59
 
50
60
  def id
@@ -62,13 +72,23 @@ module LazyRecord
62
72
  end
63
73
 
64
74
  private :id=,
75
+ :display_id_even_if_nil,
65
76
  :stringify_value,
66
- :instance_attrs_to_s,
67
- :instance_attr_accessors,
77
+ :public_attr_readers_to_s,
68
78
  :collection_counts_to_s
69
79
 
70
80
  # Class methods provided to all LazyRecord classes
71
81
  module ClassMethods
82
+ def public_attr_readers
83
+ @public_attr_readers ||= attr_readers.reject do |reader|
84
+ private_method_defined?(reader) || protected_method_defined?(reader)
85
+ end
86
+ end
87
+
88
+ def attr_readers
89
+ @attr_readers ||= []
90
+ end
91
+
72
92
  def all
73
93
  @all ||= Relation.new(model: self)
74
94
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LazyRecord
4
- VERSION = '0.3.0'
4
+ VERSION = '0.4.0'
5
5
  end
metadata CHANGED
@@ -1,29 +1,49 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lazy_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - M. Simon Borg
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-04-10 00:00:00.000000000 Z
11
+ date: 2017-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: scoped_attr_accessor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
17
34
  - - ">="
18
35
  - !ruby/object:Gem::Version
19
- version: '0'
36
+ version: 1.0.3
20
37
  type: :runtime
21
38
  prerelease: false
22
39
  version_requirements: !ruby/object:Gem::Requirement
23
40
  requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '1.0'
24
44
  - - ">="
25
45
  - !ruby/object:Gem::Version
26
- version: '0'
46
+ version: 1.0.3
27
47
  - !ruby/object:Gem::Dependency
28
48
  name: pry
29
49
  requirement: !ruby/object:Gem::Requirement