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.

BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
CafeHey
  • 5,699
  • 19
  • 82
  • 145
  • 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. – arieljuod Apr 09 '19 at 19:23
  • Ah that would be a shame, it's got lots of handy features like setting defaults. – CafeHey Apr 10 '19 at 09:17

2 Answers2

9

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.

max
  • 96,212
  • 14
  • 104
  • 165
  • I tried this, in the original question, it causes an error to do with the schema cache. – CafeHey Apr 10 '19 at 09:16
  • 2
    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. – max Apr 10 '19 at 09:31
  • O thanks, I totally mis-read it, apologies, i'll try this out thanks. – CafeHey Apr 10 '19 at 13:03
0

You can achieve the same with attr_writer

class SomeModel
  include ActiveModel::Model
  attr_writer :foo

  def foo
    @foo || 100
  end
end
Eyeslandic
  • 14,553
  • 13
  • 41
  • 54
  • 2
    This does not actually achieve the same goal since ActiveRecord::Attributes does quite a bit more than your average accessor such as typecasting. – max Apr 09 '19 at 22:07
  • You meant since `ActiveModel::Attributes` does quite a bit more than your average accessor such as typecasting and not `ActiveRecord::Attributes` I guess. – Promise Preston Jul 30 '20 at 15:51