Rails: In Rails how to use the model’s Attribute API on a tableless model
Asked Answered
C

2

6

I have a table-less model like this:

class SomeModel
  include ActiveModel::Model
  attribute :foo, :integer, default: 100
end

I’m trying to use an attribute from the link below, it works perfectly in normal models however I cannot get it to work in a tableless model.

https://api.rubyonrails.org/classes/ActiveRecord/Attributes/ClassMethods.html

This causes an undefined

I’ve tried adding active record attributes:

include ActiveRecord::Attributes

as an include too however this causes a different error related to the schema.

How do I go about using the attribute in a tableless model? Thanks.

Coincide answered 9/4, 2019 at 17:38 Comment(2)
Are you sure you should be able to do that? I mean, maybe it's not even supported to use that outside an ActiveRecord::Base object.Subacute
Ah that would be a shame, it's got lots of handy features like setting defaults.Coincide
V
10

You need to include ActiveModel::Attributes

class SomeModel
  include ActiveModel::Model
  include ActiveModel::Attributes
  attribute :foo, :integer, default: 100
end

For some reason its not included in ActiveModel::Model. This internal API was extracted out of ActiveRecord in Rails 5 so you can use it with table-less models.

Note that ActiveModel::Attributes is NOT the same thing as ActiveRecord::Attributes. ActiveRecord::Attributes is a more specialized implementation that assumes the model is backed by a database schema.

Virgel answered 9/4, 2019 at 22:35 Comment(3)
I tried this, in the original question, it causes an error to do with the schema cache.Coincide
No, you included ActiveRecord::Attributes in your question. Thats not the same thing at all although you seem to be confusing the two. I tested this in Rails 5.2.1 and it works as advertised.Virgel
O thanks, I totally mis-read it, apologies, i'll try this out thanks.Coincide
A
0

You can achieve the same with attr_writer

class SomeModel
  include ActiveModel::Model
  attr_writer :foo

  def foo
    @foo || 100
  end
end
Arthro answered 9/4, 2019 at 20:10 Comment(2)
This does not actually achieve the same goal since ActiveRecord::Attributes does quite a bit more than your average accessor such as typecasting.Virgel
You meant since ActiveModel::Attributes does quite a bit more than your average accessor such as typecasting and not ActiveRecord::Attributes I guess.Distillery

© 2022 - 2024 — McMap. All rights reserved.