
Product
Introducing Socket Firewall Enterprise: Flexible, Configurable Protection for Modern Package Ecosystems
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.
active_record-acts_as
Advanced tools
Simulates multiple-table-inheritance (MTI) for ActiveRecord models. By default, ActiveRecord only supports single-table inheritance (STI). MTI gives you the benefits of STI but without having to place dozens of empty fields into a single table.
Take a traditional e-commerce application for example:
A product has common attributes (name, price, image ...),
while each type of product has its own attributes:
for example a pen has color, a book has author and publisher and so on.
With multiple-table-inheritance you can have a products table with common columns and
a separate table for each product type, i.e. a pens table with color column.
2.56.06.0Add this line to your application's Gemfile:
gem 'active_record-acts_as'
And then execute:
$ bundle
Or install it yourself as:
$ gem install active_record-acts_as
Back to example above, all you have to do is to mark Product as actable and all product type models as acts_as :product:
class Product < ActiveRecord::Base
actable
belongs_to :store
validates_presence_of :name, :price
def info
"#{name} $#{price}"
end
end
class Pen < ActiveRecord::Base
acts_as :product
end
class Book < ActiveRecord::Base
# In case you don't wish to validate
# this model against Product
acts_as :product, validates_actable: false
end
class Store < ActiveRecord::Base
has_many :products
end
and add foreign key and type columns to products table as in a polymorphic relation. You may prefer using a migration:
change_table :products do |t|
t.integer :actable_id
t.string :actable_type
end
or use shortcut actable
change_table :products do |t|
t.actable
end
Make sure that column names do not match on parent and subclass tables,
that will make SQL statements ambiguous and invalid!
Specially DO NOT use timestamps on subclasses, if you need them define them
on parent table and they will be touched after submodel updates (You can use the option touch: false to skip this behaviour).
Now Pen and Book acts as Product, i.e. they inherit Products attributes,
methods and validations. Now you can do things like these:
Pen.create name: 'Penie!', price: 0.8, color: 'red'
# => #<Pen id: 1, color: "red">
Pen.where price: 0.8
# => [#<Pen id: 1, color: "red">]
pen = Pen.where(name: 'new pen', color: 'black').first_or_initialize
# => #<Pen id: nil, color: "black">
pen.name
# => "new pen"
Product.where price: 0.8
# => [#<Product id: 1, name: "Penie!", price: 0.8, store_id: nil, actable_id: 1, actable_type: "Pen">]
pen = Pen.new
pen.valid?
# => false
pen.errors.full_messages
# => ["Name can't be blank", "Price can't be blank", "Color can't be blank"]
Pen.first.info
# => "Penie! $0.8"
On the other hand you can always access a specific object from its parent by calling specific method on it:
Product.first.specific
# => #<Pen ...>
If you have to come back to the parent object from the specific, the acting_as returns the parent element:
Pen.first.acting_as
# => #<Product ...>
Likewise, actables converts a relation of specific objects to their parent objects:
Pen.where(...).actables
# => [#<Product ...>, ...]
In has_many case you can use subclasses:
store = Store.create
store.products << Pen.create
store.products.first
# => #<Product: ...>
You can give a name to all methods in :as option:
class Product < ActiveRecord::Base
actable as: :producible
end
class Pen < ActiveRecord::Base
acts_as :product, as: :producible
end
change_table :products do |t|
t.actable as: :producible
end
acts_as support all has_one options, where defaults are there:
as: :actable, dependent: :destroy, validate: false, autosave: true
Make sure you know what you are doing when overwriting validate or autosave options.
You can pass scope to acts_as as in has_one:
acts_as :person, -> { includes(:friends) }
actable support all belongs_to options, where defaults are these:
polymorphic: true, dependent: :destroy, autosave: true
Make sure you know what you are doing when overwriting polymorphic option.
If your actable and acts_as models are namespaced, you need to configure them like this:
class MyApp::Product < ApplicationRecord
actable inverse_of: :product
end
class MyApp::Pen < ApplicationRecord
acts_as :product, class_name: 'MyApp::Product'
end
Multiple acts_as in the same class are not supported!
Replace acts_as_superclass in models with actable and if you where using
:as_relation_superclass option on create_table remove it and use t.actable on column definitions.
To use this library custom RSpec matchers, you must require the rspec/acts_as_matchers file.
Examples:
require "active_record/acts_as/matchers"
RSpec.describe "Pen acts like a Product" do
it { is_expected.to act_as(:product) }
it { is_expected.to act_as(Product) }
it { expect(Person).to act_as(:product) }
it { expect(Person).to act_as(Product) }
end
RSpec.describe "Product is actable" do
it { expect(Product).to be_actable }
end
git checkout -b my-new-feature)rspec)git commit -am 'Add some feature')git push origin my-new-feature)FAQs
Unknown package
We found that active_record-acts_as demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.

Security News
Open source dashboard CNAPulse tracks CVE Numbering Authorities’ publishing activity, highlighting trends and transparency across the CVE ecosystem.

Product
Detect malware, unsafe data flows, and license issues in GitHub Actions with Socket’s new workflow scanning support.