anchormodel 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/doc/index.html CHANGED
@@ -89,7 +89,14 @@
89
89
 
90
90
  <p>This is why Anchormodel is strictly relying on String keys corresponding to the entries of an Anchormodel.</p>
91
91
 
92
- <h1 id="label-Example">Example</h1>
92
+ <h1 id="label-Installation">Installation</h1>
93
+ <ol><li>
94
+ <p>Add gem to Gemfile: <code>gem &#39;anchormodel&#39;</code></p>
95
+ </li><li>
96
+ <p>In <code>application_record.rb</code>, add in the class body: <code>include Anchormodel::ModelMixin</code></p>
97
+ </li></ol>
98
+
99
+ <h1 id="label-Basic+example">Basic example</h1>
93
100
 
94
101
  <p><code>app/anchormodels/role.rb</code>:</p>
95
102
 
@@ -116,7 +123,11 @@
116
123
 
117
124
  <pre class="code ruby"><code class="ruby"><span class='comment'># The DB table `users` must have a String column `users.role`
118
125
  </span><span class='kw'>class</span> <span class='const'>User</span> <span class='op'>&lt;</span> <span class='const'>ApplicationRecord</span>
119
- <span class='id identifier rubyid_belongs_to_anchormodel'>belongs_to_anchormodel</span> <span class='symbol'>:role</span>
126
+ <span class='comment'># If `users.role` has an `NOT NULL` constraint, use:
127
+ </span> <span class='id identifier rubyid_belongs_to_anchormodel'>belongs_to_anchormodel</span> <span class='symbol'>:role</span>
128
+
129
+ <span class='comment'># If `users.role` can be `NULL`, use the following instead:
130
+ </span> <span class='id identifier rubyid_belongs_to_anchormodel'>belongs_to_anchormodel</span> <span class='symbol'>:role</span><span class='comma'>,</span> <span class='label'>optional:</span> <span class='kw'>true</span>
120
131
  <span class='kw'>end</span>
121
132
  </code></pre>
122
133
 
@@ -135,18 +146,89 @@
135
146
 
136
147
  <span class='comment'># Pretty print a user&#39;s role, e.g. using the Rails FastGettext gem:
137
148
  </span><span class='id identifier rubyid_puts'>puts</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>User </span><span class='embexpr_beg'>#{</span><span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_name'>name</span><span class='embexpr_end'>}</span><span class='tstring_content'> has role </span><span class='embexpr_beg'>#{</span><span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_role'>role</span><span class='period'>.</span><span class='id identifier rubyid_label'>label</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span><span class='rparen'>)</span>
138
- </code></pre>
139
149
 
140
- <h1 id="label-Installation">Installation</h1>
141
- <ol><li>
142
- <p>Add gem to Gemfile: <code>gem &#39;anchormodel&#39;</code></p>
150
+ <span class='comment'># Check whether @user has role admin
151
+ </span><span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_role'>role</span><span class='period'>.</span><span class='id identifier rubyid_admin?'>admin?</span> <span class='comment'># true if and only if the role is admin (false otherwise)
152
+ </span></code></pre>
153
+
154
+ <h1 id="label-Rails+Enum+style+model+methods">Rails Enum style model methods</h1>
155
+
156
+ <p>By default, Anchormodel adds three kinds of methods for each key to the model:</p>
157
+ <ul><li>
158
+ <p>a reader (getter)</p>
143
159
  </li><li>
144
- <p>In <code>application_record.rb</code>, add in the class body: <code>include Anchormodel::ModelMixin</code></p>
145
- </li></ol>
160
+ <p>a writer (setter)</p>
161
+ </li><li>
162
+ <p>a Rails scope</p>
163
+ </li></ul>
164
+
165
+ <p>For instance:</p>
166
+
167
+ <pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>User</span> <span class='op'>&lt;</span> <span class='const'>ApplicationRecord</span>
168
+ <span class='id identifier rubyid_belongs_to_anchormodel'>belongs_to_anchormodel</span> <span class='symbol'>:role</span> <span class='comment'># where Role has keys :guest, :manager and :admin
169
+ </span> <span class='id identifier rubyid_belongs_to_anchormodel'>belongs_to_anchormodel</span> <span class='symbol'>:shape</span> <span class='comment'># where Shape has keys :circle and :rectangle
170
+ </span><span class='kw'>end</span>
171
+
172
+ <span class='comment'># User now implements the following methods, given that @user is retrieved as follows:
173
+ </span><span class='ivar'>@user</span> <span class='op'>=</span> <span class='const'>User</span><span class='period'>.</span><span class='id identifier rubyid_first'>first</span> <span class='comment'># for example
174
+ </span>
175
+ <span class='comment'># Readers
176
+ </span><span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_guest?'>guest?</span> <span class='comment'># same as @user.role.guest?
177
+ </span><span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_manager?'>manager?</span>
178
+ <span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_admin?'>admin?</span>
179
+ <span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_rectangle?'>rectangle?</span> <span class='comment'># same as @user.shape.rectangle?
180
+ </span><span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_circle?'>circle?</span>
181
+ <span class='comment'># Writers
182
+ </span><span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_guest!'>guest!</span> <span class='comment'># same as @user.role = Role.find(:guest)
183
+ </span><span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_manager!'>manager!</span>
184
+ <span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_admin!'>admin!</span>
185
+ <span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_rectangle!'>rectangle!</span> <span class='comment'># same as @user.shape = Shape.find(:rectangle)
186
+ </span><span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_circle!'>circle!</span>
187
+ <span class='comment'># Scopes
188
+ </span><span class='const'>User</span><span class='period'>.</span><span class='id identifier rubyid_guest'>guest</span> <span class='comment'># same as User.where(role: &#39;guest&#39;)
189
+ </span><span class='const'>User</span><span class='period'>.</span><span class='id identifier rubyid_manager'>manager</span>
190
+ <span class='const'>User</span><span class='period'>.</span><span class='id identifier rubyid_admin'>admin</span>
191
+ <span class='const'>User</span><span class='period'>.</span><span class='id identifier rubyid_rectangle'>rectangle</span> <span class='comment'># same as User.where(shape: &#39;rectangle&#39;)
192
+ </span><span class='const'>User</span><span class='period'>.</span><span class='id identifier rubyid_circle'>circle</span>
193
+ </code></pre>
194
+
195
+ <p>This behavior is similar as the one from Rails Enums. If you want to disable it, use:</p>
196
+
197
+ <pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>User</span> <span class='op'>&lt;</span> <span class='const'>ApplicationRecord</span>
198
+ <span class='id identifier rubyid_belongs_to_anchormodel'>belongs_to_anchormodel</span> <span class='symbol'>:role</span><span class='comma'>,</span> <span class='label'>model_readers:</span> <span class='kw'>false</span><span class='comma'>,</span> <span class='label'>model_writers:</span> <span class='kw'>false</span><span class='comma'>,</span> <span class='label'>model_scopes:</span> <span class='kw'>false</span>
199
+ <span class='comment'># or, equivalent, to disable all at once:
200
+ </span> <span class='id identifier rubyid_belongs_to_anchormodel'>belongs_to_anchormodel</span> <span class='symbol'>:role</span><span class='comma'>,</span> <span class='label'>model_methods:</span> <span class='kw'>false</span>
201
+ <span class='kw'>end</span>
202
+ </code></pre>
203
+
204
+ <h1 id="label-Calling+a+column+differently+than+the+Anchormodel">Calling a column differently than the Anchormodel</h1>
205
+
206
+ <p>If your column name (and the model’s attribute) is called differently than the Anchormodel, you may give the Anchormodel’s class as the second argument. For example:</p>
207
+
208
+ <pre class="code ruby"><code class="ruby"><span class='comment'># app/anchormodels/color.rb
209
+ </span><span class='kw'>class</span> <span class='const'>Color</span> <span class='op'>&lt;</span> <span class='const'><span class='object_link'><a href="Anchormodel.html" title="Anchormodel (class)">Anchormodel</a></span></span>
210
+ <span class='id identifier rubyid_new'>new</span> <span class='symbol'>:green</span>
211
+ <span class='id identifier rubyid_new'>new</span> <span class='symbol'>:red</span>
212
+ <span class='kw'>end</span>
213
+
214
+ <span class='comment'># app/models/user.rb
215
+ </span><span class='kw'>class</span> <span class='const'>User</span> <span class='op'>&lt;</span> <span class='const'>ApplicationRecord</span>
216
+ <span class='id identifier rubyid_belongs_to_anchormodel'>belongs_to_anchormodel</span> <span class='symbol'>:favorite_color</span><span class='comma'>,</span> <span class='const'>Color</span>
217
+ <span class='kw'>end</span>
218
+ </code></pre>
219
+
220
+ <h2 id="label-Having+multiple+attributes+to+the+same+Anchormodel">Having multiple attributes to the same Anchormodel</h2>
221
+
222
+ <p>If you want to have multiple attributes in the same model pointing to the same Anchormodel, you need to disable <code>model_methods</code> for at least one of them (otherwise the model methods will clash in your model class):</p>
223
+
224
+ <pre class="code ruby"><code class="ruby"><span class='comment'># app/models/user.rb
225
+ </span> <span class='id identifier rubyid_belongs_to_anchormodel'>belongs_to_anchormodel</span> <span class='symbol'>:role</span>
226
+ <span class='id identifier rubyid_belongs_to_anchormodel'>belongs_to_anchormodel</span> <span class='symbol'>:secondary_role</span><span class='comma'>,</span> <span class='const'>Role</span><span class='comma'>,</span> <span class='label'>model_methods:</span> <span class='kw'>false</span>
227
+ </code></pre>
146
228
  </div></div>
147
229
 
148
230
  <div id="footer">
149
- Generated on Wed Jan 18 11:24:43 2023 by
231
+ Generated on Tue Jan 24 20:27:58 2023 by
150
232
  <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
151
233
  0.9.28 (ruby-3.1.3).
152
234
  </div>
data/doc/method_list.html CHANGED
@@ -62,7 +62,7 @@
62
62
 
63
63
  <li class="odd ">
64
64
  <div class="item">
65
- <span class='object_link'><a href="Anchormodel/Attribute.html#anchor_class-instance_method" title="Anchormodel::Attribute#anchor_class (method)">#anchor_class</a></span>
65
+ <span class='object_link'><a href="Anchormodel/Attribute.html#anchormodel_class-instance_method" title="Anchormodel::Attribute#anchormodel_class (method)">#anchormodel_class</a></span>
66
66
  <small>Anchormodel::Attribute</small>
67
67
  </div>
68
68
  </li>
@@ -100,7 +100,7 @@
100
100
  </div>
101
101
 
102
102
  <div id="footer">
103
- Generated on Wed Jan 18 11:24:43 2023 by
103
+ Generated on Tue Jan 24 20:27:59 2023 by
104
104
  <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
105
105
  0.9.28 (ruby-3.1.3).
106
106
  </div>
@@ -13,11 +13,11 @@ class Anchormodel::ActiveModelTypeValue < ActiveModel::Type::Value
13
13
  def serialize(value)
14
14
  return case value
15
15
  when Symbol, String
16
- unless @attribute.anchor_class.valid_keys.include?(value.to_sym)
16
+ unless @attribute.anchormodel_class.valid_keys.include?(value.to_sym)
17
17
  fail("Attempt to set #{@attribute.attribute_name} to unsupported key #{value.inspect}.")
18
18
  end
19
19
  value.to_s
20
- when @attribute.anchor_class
20
+ when @attribute.anchormodel_class
21
21
  value.key.to_s
22
22
  when nil
23
23
  nil
@@ -27,8 +27,8 @@ class Anchormodel::ActiveModelTypeValue < ActiveModel::Type::Value
27
27
  end
28
28
 
29
29
  def deserialize(value)
30
- return value if value.is_a?(@attribute.anchor_class)
31
- return @attribute.anchor_class.find(value)
30
+ return value if value.is_a?(@attribute.anchormodel_class)
31
+ return @attribute.anchormodel_class.find(value)
32
32
  end
33
33
 
34
34
  def changed?(old_value, new_value, _new_value_before_type_cast)
@@ -3,22 +3,17 @@
3
3
  # It is instanciated when {Anchormodel::ModelMixin#belongs_to_anchormodel} is used.
4
4
  class Anchormodel::Attribute
5
5
  attr_reader :attribute_name
6
+ attr_reader :anchormodel_class
6
7
  attr_reader :optional
7
8
 
8
9
  # @param model_class [ActiveRecord::Base] The Rails model where {Anchormodel::ModelMixin#belongs_to_anchormodel} is used
9
10
  # @param attribute_name [String,Symbol] The name and database column of the attribute
10
- # @param anchor_class_name [String] Name of the Anchormodel class (omit if attribute `:foo_bar` holds an `FooBar`)
11
+ # @param anchormodel_class [Class] Class of the Anchormodel (omit if attribute `:foo_bar` holds an `FooBar`)
11
12
  # @param optional [Boolean] If true, a presence validation is added to the model.
12
- def initialize(model_class, attribute_name, anchor_class_name = nil, optional = false)
13
+ def initialize(model_class, attribute_name, anchormodel_class = nil, optional = false)
13
14
  @model_class = model_class
14
15
  @attribute_name = attribute_name.to_sym
15
- @anchor_class_name = anchor_class_name || attribute_name.to_s.classify
16
+ @anchormodel_class = anchormodel_class
16
17
  @optional = optional
17
18
  end
18
-
19
- # Getter for the Anchormodel class based on the name passed to the initializer.
20
- # We are loading the anchor class lazily, because the model mixin instanciates this statically -> avoid premature anchor class loading
21
- def anchor_class
22
- @anchor_class ||= @anchor_class_name.constantize
23
- end
24
19
  end
@@ -11,11 +11,24 @@ module Anchormodel::ModelMixin
11
11
  # Creates an attribute linking to an Anchormodel. The attribute should be
12
12
  # present in the DB and the column should be named the same as `attribute_name.`
13
13
  # @param attribute_name [String,Symbol] The name and database column of the attribute
14
- # @param anchor_class_name [String] Name of the Anchormodel class (omit if attribute `:foo_bar` holds a `FooBar`)
14
+ # @param anchormodel_class [Class] Class of the Anchormodel (omit if attribute `:foo_bar` holds a `FooBar`)
15
15
  # @param optional [Boolean] If true, a presence validation is added to the model.
16
- def belongs_to_anchormodel(attribute_name, anchor_class_name = nil, optional: false)
16
+ # @param model_readers [Boolean] If true, the model is given an ActiveRecord::Enum style method `my_model.my_key?` reader for each key in the anchormodel
17
+ # @param model_writers [Boolean] If true, the model is given an ActiveRecord::Enum style method `my_model.my_key!` writer for each key in the anchormodel
18
+ # @param model_scopes [Boolean] If true, the model is given an ActiveRecord::Enum style scope `MyModel.mykey` for each key in the anchormodel
19
+ # @param model_methods [Boolean, NilClass] If non-nil, this mass-assigns and overrides `model_readers`, `model_writers` and `model_scopes`
20
+ def belongs_to_anchormodel(attribute_name, anchormodel_class = nil, optional: false, model_readers: true,
21
+ model_writers: true, model_scopes: true, model_methods: nil)
22
+ anchormodel_class ||= attribute_name.to_s.classify.constantize
17
23
  attribute_name = attribute_name.to_sym
18
- attribute = Anchormodel::Attribute.new(self, attribute_name, anchor_class_name, optional)
24
+ attribute = Anchormodel::Attribute.new(self, attribute_name, anchormodel_class, optional)
25
+
26
+ # Mass configurations if model_methods was specfied
27
+ unless model_methods.nil?
28
+ model_readers = model_methods
29
+ model_writers = model_methods
30
+ model_scopes = model_methods
31
+ end
19
32
 
20
33
  # Register attribute
21
34
  self.anchormodel_attributes = anchormodel_attributes.merge({ attribute_name => attribute }).freeze
@@ -41,6 +54,43 @@ module Anchormodel::ModelMixin
41
54
 
42
55
  # Supply serializer and deserializer
43
56
  attribute attribute_name, active_model_type_value
57
+
58
+ # Create ActiveRecord::Enum style reader directly in the model if asked to do so
59
+ # For a model User with anchormodel Role with keys :admin and :guest, this creates user.admin? and user.guest? (returning true iff role is admin/guest)
60
+ if model_readers
61
+ anchormodel_class.all.each do |entry|
62
+ if respond_to?(:"#{entry.key}?")
63
+ fail("Anchormodel reader #{entry.key}? already defined for #{self}, add `model_readers: false` to `belongs_to_anchormodel :#{attribute_name}`.")
64
+ end
65
+ define_method(:"#{entry.key}?") do
66
+ public_send(attribute_name.to_s) == entry
67
+ end
68
+ end
69
+ end
70
+
71
+ # Create ActiveRecord::Enum style writer directly in the model if asked to do so
72
+ # For a model User with anchormodel Role with keys :admin and :guest, this creates user.admin! and user.guest! (setting the role to admin/guest)
73
+ if model_writers
74
+ anchormodel_class.all.each do |entry|
75
+ if respond_to?(:"#{entry.key}!")
76
+ fail("Anchormodel writer #{entry.key}! already defined for #{self}, add `model_writers: false` to `belongs_to_anchormodel :#{attribute_name}`.")
77
+ end
78
+ define_method(:"#{entry.key}!") do
79
+ public_send(:"#{attribute_name.to_s}=", entry)
80
+ end
81
+ end
82
+ end
83
+
84
+ # Create ActiveRecord::Enum style scope directly in the model class if asked to do so
85
+ # For a model User with anchormodel Role with keys :admin and :guest, this creates user.admin! and user.guest! (setting the role to admin/guest)
86
+ if model_scopes
87
+ anchormodel_class.all.each do |entry|
88
+ if respond_to?(entry.key)
89
+ fail("Anchormodel scope #{entry.key} already defined for #{self}, add `model_scopes: false` to `belongs_to_anchormodel :#{attribute_name}`.")
90
+ end
91
+ scope(entry.key, ->{where(attribute_name => entry.key)})
92
+ end
93
+ end
44
94
  end
45
95
  end
46
96
  end
@@ -2,7 +2,7 @@ class Anchormodel
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- PATCH = 0
5
+ PATCH = 1
6
6
 
7
7
  EDGE = false
8
8
 
data/lib/anchormodel.rb CHANGED
@@ -52,6 +52,11 @@ class Anchormodel
52
52
 
53
53
  # Register valid keys
54
54
  valid_keys << key
55
+
56
+ # Define boolean reader
57
+ self.class.define_method(:"#{key}?") do
58
+ @key == key
59
+ end
55
60
  end
56
61
 
57
62
  def ==(other)
@@ -1,6 +1,10 @@
1
1
  class UserTest < Minitest::Test
2
2
  def setup; end
3
3
 
4
+ def teardown
5
+ User.destroy_all
6
+ end
7
+
4
8
  def test_retrieval
5
9
  assert_equal Role.find(:guest), Role.find('guest')
6
10
  end
@@ -17,7 +21,11 @@ class UserTest < Minitest::Test
17
21
  )
18
22
  end
19
23
 
20
- def test_setters_and_getters
24
+ def test_missing_key
25
+ assert_raises { Role.find(:does_not_exist) }
26
+ end
27
+
28
+ def test_basic_setters_and_getters
21
29
  u = User.create!(role: 'guest', locale: 'de') # String assignment
22
30
  assert_equal Role.find(:guest), u.role
23
31
  assert_equal Locale.find(:de), u.locale
@@ -48,4 +56,60 @@ class UserTest < Minitest::Test
48
56
  assert_equal(0, Role.find(:moderator) <=> Role.find(:moderator))
49
57
  assert Role.find(:moderator) < Role.find(:admin)
50
58
  end
59
+
60
+ def test_presence_validation
61
+ valentine = User.new
62
+ assert_raises(ActiveRecord::RecordInvalid) { valentine.save! }
63
+ end
64
+
65
+ def test_alternative_column_name
66
+ ben = User.create!(
67
+ role: Role.find(:moderator),
68
+ secondary_role: Role.find(:admin),
69
+ locale: Locale.find(:de)
70
+ )
71
+ assert_equal(Role.find(:moderator), ben.role)
72
+ assert_equal(Role.find(:admin), ben.secondary_role)
73
+ assert_equal(Locale.find(:de), ben.locale)
74
+ end
75
+
76
+ def test_optional_attribute
77
+ jenny = User.create!(role: :admin, locale: :en)
78
+ assert_nil jenny.secondary_role
79
+ end
80
+
81
+ def test_model_readers_and_writers
82
+ pia = User.new
83
+ pia.admin!
84
+ assert_equal true, pia.admin?
85
+ assert_equal false, pia.guest?
86
+ assert_equal Role.find(:admin), pia.role
87
+ end
88
+
89
+ def test_model_scopes
90
+ User.create!(role: :admin, locale: :en)
91
+ User.create!(role: :admin, locale: :en)
92
+ User.create!(role: :moderator, locale: :en)
93
+ assert_equal 2, User.admin.count
94
+ assert_equal 1, User.moderator.count
95
+ assert_equal 0, User.guest.count
96
+ end
97
+
98
+ def test_model_readers_writers_with_different_class_name
99
+ pia = User.new(locale: :en)
100
+ pia.de!
101
+ assert_equal true, pia.de?
102
+ assert_equal false, pia.fr?
103
+ assert_equal Locale.find(:de), pia.preferred_locale
104
+ assert_equal Locale.find(:en), pia.locale
105
+ end
106
+
107
+ def test_model_scopes_with_different_class_name
108
+ User.create!(role: :admin, locale: :en, preferred_locale: :de)
109
+ User.create!(role: :admin, locale: :en, preferred_locale: :de)
110
+ User.create!(role: :admin, locale: :en, preferred_locale: :fr)
111
+ assert_equal 2, User.de.count
112
+ assert_equal 1, User.fr.count
113
+ assert_equal 0, User.en.count
114
+ end
51
115
  end
@@ -1,4 +1,6 @@
1
1
  class User < ApplicationRecord
2
2
  belongs_to_anchormodel :role
3
- belongs_to_anchormodel :locale
3
+ belongs_to_anchormodel :secondary_role, Role, optional: true, model_readers: false, model_writers: false, model_scopes: false
4
+ belongs_to_anchormodel :locale, model_methods: false
5
+ belongs_to_anchormodel :preferred_locale, Locale
4
6
  end
@@ -2,7 +2,9 @@ class CreateUsers < ActiveRecord::Migration[7.0]
2
2
  def change
3
3
  create_table :users do |t|
4
4
  t.string :role
5
+ t.string :secondary_role
5
6
  t.string :locale
7
+ t.string :preferred_locale, null: false, default: :en
6
8
 
7
9
  t.timestamps
8
10
  end
@@ -10,12 +10,14 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema[7.0].define(version: 2023_01_07_173151) do
13
+ ActiveRecord::Schema[7.0].define(version: 2023_01_24_084241) do
14
14
  create_table "users", force: :cascade do |t|
15
15
  t.string "role"
16
16
  t.string "locale"
17
17
  t.datetime "created_at", null: false
18
18
  t.datetime "updated_at", null: false
19
+ t.string "secondary_role"
20
+ t.string "preferred_locale", default: "en", null: false
19
21
  end
20
22
 
21
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anchormodel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sandro Kalbermatter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-18 00:00:00.000000000 Z
11
+ date: 2023-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -166,6 +166,7 @@ files:
166
166
  - README.md
167
167
  - Rakefile
168
168
  - anchormodel.gemspec
169
+ - bin/rails
169
170
  - doc/Anchormodel.html
170
171
  - doc/Anchormodel/ActiveModelTypeValue.html
171
172
  - doc/Anchormodel/Attribute.html