It is possible to use the new ActiveRecord::Attributes API in a PORO?
Asked Answered
B

4

6

I usually include ActiveModel::Model into some PORO (for example for a FormObject::SignUp). I've read about the new Rails 5 ActiveRecord::Attribute API, and I thought I will be able to use it for simpler casting, but not luck.

For example, given

class FormObject::SignUp
  include ActiveRecord::Model
  include ActiveRecord::Attributes

  attribute :birthday, :date
  validates :birthday, presence: true
end

I got an NameError: undefined local variable or method `reload_schema_from_cache' for FormObjects::SignUp:Class exception when I try to instantiate it.

It is not expected to be used standalone? Thanks

Bluecoat answered 15/2, 2017 at 14:45 Comment(2)
A big part of activemodel attributes is dealing with the database (e.g translating the attribute to a real sql query) so it makes sense to me if this doesn't work .Proportionable
@Joel_Blum they could have done it to work as a virtual attribute.. I mean, unless you read / write to the db it shouldn't explote.Bluecoat
B
4

Rails >=5.2

This is now possible in Rails 5.2.

As of Rails 5.2 (#30985), ActiveModel::Atrributes is now available to use in POROs (at least POROs that include ActiveModel::Model)...

Rails <5.2

Utilizing the gem ActiveModelAttributesis the only easy way I've been able to find to do this. Depending on your use case, it will probably make sense to use that gem or take a different approach.

Here is the gem: https://github.com/Azdaroth/active_model_attributes

Side note: I got feedback that link-only answers can disappear. If this link disappears, then this answer does indeed become invalid since that will likely mean the gem dosen't exist anymore.

Beichner answered 17/7, 2017 at 22:45 Comment(2)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From ReviewPursuance
I'm not sure that applies in this case. it isn't a link to a solution per se, as much as it is a link to a library. Still, I mentioned the gem by name. Hope that helps.Beichner
M
2

ActiveModel::Attributes is available as of Rails 5.2 (PR).

Try this:

class FormObject::SignUp
  include ActiveModel::Model
  include ActiveModel::Attributes

  attribute :birthday, :date
  validates :birthday, presence: true
end
Merlynmermaid answered 23/1, 2019 at 0:7 Comment(0)
F
1

If you look at the documentation it seems that this module cannot be used stand-alone, as it makes a lot of assumptions (mostly about a schema-backed model).

Even if you try with the define_attribute method, you still need to provide implementation for other class methods, like attribute_types.

What's wrong with using ActiveModel::Model in Rails 5?

class Poro
  include ActiveModel::Model

  attr_accessor :foo
end
Flavoring answered 15/2, 2017 at 14:59 Comment(3)
Of course I want to still use it, the idea is to also use the typecasting feature.. for example, if you do Poro.new.foo = '2017-02-15' it will cast it automatically to a date.. just that. I've glimpsed above the documentation and it's not clear that it shouldn't be used standanlone, do you have a link?Bluecoat
This is precisely why I am looking for this behavior as well. ActiveModel is a very powerful pattern. Its a shame that ActiveModel won't work in this fashion, yet.Affaire
How can you use @object.attributes ?Ricercar
B
0

I've submitted an issue and they replied that it's not supported currently, but it will be in the future.

Link: https://github.com/rails/rails/issues/28020#event-963668657

Bluecoat answered 15/2, 2017 at 19:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.