chaadow / active_record-acts_as Goto Github PK
View Code? Open in Web Editor NEWSimulate multi-table inheritance for ActiveRecord models
Home Page: https://chaadow.github.io/active_record-acts_as/
License: MIT License
Simulate multi-table inheritance for ActiveRecord models
Home Page: https://chaadow.github.io/active_record-acts_as/
License: MIT License
ruby 2.3.3
rails 4.2.5
class Party < ActiveRecord::Base
actable
validates :name, presence: true
end
class Client < ActiveRecord::Base
acts_as :party, dependent: :destroy
validates :preferred_phone_number, presence: true
end
When I create a client with invalid attributes, my errors hash look like this:
@messages={
:name=>["can't be blank", "can't be blank", "can't be blank"],
:preferred_phone_number=>["can't be blank", "can't be blank"],
:"actable.name"=>["can't be blank"],
:"actable.preferred_phone_number"=>["can't be blank"]
}
This results in my errors on the form looking something like this:
10 errors prohibited this client from being saved:
This makes no sense . . .
i want to provide a single form for creating records of any type that inherits from my base model. is there a way to find all the models that inherit from it so i can provide a dropdown?
Thank you for this great gem. Very useful and reliable. Unfortunately I'm stuck right now and I hope you can point me to a general procedure to solve it.
I'm following this guide to create a nested form. In this example one show
has many seasons
and one season
has many episodes
. Now imagine the episode
model would be actable. sad_episodes
act_as episodes
and funny_episodes
act_as episodes
as well. How would I implement a nested form to create shows
with funny_episodes
or sad_episodes
?
I am upgrading rails project from rails 3.2.21 version to 5.2.8.
Migration details.
class CreateDevices < ActiveRecord::Migration[6.0]
def change
create_table :devices do |t|
t.actable as: :as_device
t.timestamps
end
end
end
class CreateGateways < ActiveRecord::Migration[6.0]
def change
create_table :gateways do |t|
t.actable as: :as_gateway
t.timestamps
end
end
end
class CreateUserGrants < ActiveRecord::Migration[6.0]
def change
create_table :user_grants do |t|
t.string :grantable_type
t.string :grantable_id
t.timestamps
end
end
end
I have below models.
class Device < ApplicationRecord
actable as: :as_device
has_many :user_grants, as: :grantable, dependent: :destroy, validate: false
end
class Gateway < ApplicationRecord
actable as: :as_gateway
acts_as :device, as: :as_device
has_many :user_grants, as: :grantable, dependent: :destroy, validate: false
end
class UserGrant < ApplicationRecord
belongs_to :grantable, polymorphic: true
end
Steps to create record in user_grants
table.
@device = Device.new
@device.save
@gateway = Gateway.new
@gateway.device = @device
@gateway.save
@gateway.user_grants.create
#<UserGrant id: 3, grantable_type: "Gateway", grantable_id: "3", created_at: "2023-08-30 17:38:45", updated_at: "2023-08-30 17:38:45">
As per above output result user_grant record has grantable_type column value as "Gateway" but when using acts_as_relation gem it is coming as "Device" . is it bug in active_record-acts_as gem or active_record-acts_as gem has changed this behaviour intentionally ?
Hi,
Is there a dev roadmap for getting this feature in the gem?
Thanks
The example:
Pen.where(name: 'new pen', color: 'black').order(price: desc)
Dont works.
Am I missing something or this is a feature not implemented?
If a method like this is defined on the supermodel:
def keyword_method(test: 1)
'keyword_method'
end
In ruby 3, calling it from the submodel with kwargs results in an ArgumentError.
It looks like scope_for_create
was recently changed in the Rails code, breaking the override in ActiveRecord::ActsAs::ScopeForCreate
.
I haven't yet fully analysed the change but it seems like one is supposed to implement a separate method values_for_create
instead. Did you already encounter this yourself and are working on this? Otherwise I'd check it out more thoroughly and create a PR some time in the next couple of days.
When testing my application using Rspec, when calling an association to a model that uses actable to branch onto other related models using acts_as. The call returns both types of records.
When using this method in production it only returns the upper level (actable) records and not the lower lever (acts_as) records.
Why does is this not the case when using Rspec and is there are way to resolve this so that it acts as it does in production?
Example:
class Task::Block < ApplicationRecord
has_many :activities, class_name: "Task::Activity", dependent: :destroy
end
class Task::Activity < ApplicationRecord
actable inverse_of: :activity
end
class Task::Assessment < ApplicationRecord
acts_as :activity, class_name: "Task::Activity"
end
I have a database that has two different behavior. In one scenario, I am saving content directly into that table and I do not want to have its entries as a part of the actable table. But for another scenario I want it to act as child table to actable. Does this gem provide support for this kind of behavior?
I am trying to create a basic example using ActivieAdmin but get an error when navigating to the MultipleChoice admin page with this route: admin/multiple_choices that should render the with code below.
ActiveAdmin.register MultipleChoice do
end
class Activity < ActiveRecord::Base
actable
end
class MultipleChoice < ActiveRecord::Base
acts_as :activity
end
using
ruby 2.3.3
Rails 4.2.0
ERROR
Showing /Users/lancecoe/.rvm/gems/ruby-2.3.3/gems/activeadmin-1.0.0/app/views/active_admin/resource/index.html.arb where line #2 raised
NameError in Admin::MultipleChoices#index
.../activeadmin-1.0.0/app/views/active_admin/resource/index.html.arb where line #2 raised:
uninitialized constant Activity::Actable
raise NameError.new("uninitialized constant #{candidates.first}", candidates.first)
Rails.root: /Users/lancecoe/Desktop/aweza-admin
Application Trace | Framework Trace | Full Trace
activerecord (4.2.0) lib/active_record/inheritance.rb:158:in `compute_type'
activerecord (4.2.0) lib/active_record/reflection.rb:271:in `compute_class'
activerecord (4.2.0) lib/active_record/reflection.rb:267:in `klass'
ransack (1.8.2) lib/ransack/adapters/active_record/context.rb:59:in `attribute_method?'
ransack (1.8.2) lib/ransack/nodes/grouping.rb:131:in `attribute_method?'
ransack (1.8.2) lib/ransack/search.rb:97:in `method_missing'
ransack (1.8.2) lib/ransack/helpers/form_builder.rb:10:in `value'
actionview (4.2.0) lib/action_view/helpers/tags/select.rb:16:in `block in render'
actionview (4.2.0) lib/action_view/helpers/tags/select.rb:16:in `fetch'
actionview (4.2.0) lib/action_view/helpers/tags/select.rb:16:in `render'
actionview (4.2.0) lib/action_view/helpers/form_options_helper.rb:163:in `select'
actionview (4.2.0) lib/action_view/helpers/form_options_helper.rb:777:in `select'
formtastic (3.1.5) lib/formtastic/inputs/select_input.rb:173:in `select_html'
formtastic (3.1.5) lib/formtastic/inputs/select_input.rb:168:in `block in to_html'
actionview (4.2.0) lib/action_view/helpers/capture_helper.rb:38:in `block in capture'
actionview (4.2.0) lib/action_view/helpers/capture_helper.rb:200:in `with_output_buffer'
actionview (4.2.0) lib/action_view/helpers/capture_helper.rb:38:in `capture'
activeadmin (1.0.0) lib/active_admin/inputs/filters/base.rb:12:in `input_wrapping'
formtastic (3.1.5) lib/formtastic/inputs/select_input.rb:166:in `to_html'
formtastic (3.1.5) lib/formtastic/helpers/input_helper.rb:242:in `input'
activeadmin_addons (0.11.0) lib/activeadmin_addons/support/enumerize_formtastic_support.rb:13:in `input'
activeadmin (1.0.0) lib/active_admin/filters/forms.rb:14:in `filter'
activeadmin (1.0.0) lib/active_admin/filters/forms.rb:62:in `block (2 levels) in active_admin_filters_form_for'
activeadmin (1.0.0) lib/active_admin/filters/forms.rb:58:in `each'
activeadmin (1.0.0) lib/active_admin/filters/forms.rb:58:in `block in active_admin_filters_form_for'
actionview (4.2.0) lib/action_view/helpers/capture_helper.rb:38:in `block in capture'
actionview (4.2.0) lib/action_view/helpers/capture_helper.rb:200:in `with_output_buffer'
actionview (4.2.0) lib/action_view/helpers/capture_helper.rb:38:in `capture'
actionview (4.2.0) lib/action_view/helpers/form_helper.rb:444:in `form_for'
activeadmin (1.0.0) lib/active_admin/filters/forms.rb:57:in `active_admin_filters_form_for'
arbre (1.1.1) lib/arbre/element.rb:180:in `method_missing'
activeadmin (1.0.0) lib/active_admin/filters/resource_extension.rb:146:in `block in filters_sidebar_section'
activeadmin (1.0.0) lib/active_admin/views/components/sidebar_section.rb:25:in `instance_exec'
activeadmin (1.0.0) lib/active_admin/views/components/sidebar_section.rb:25:in `build_sidebar_content'
activeadmin (1.0.0) lib/active_admin/views/components/sidebar_section.rb:13:in `build'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:30:in `block in build_tag'
arbre (1.1.1) lib/arbre/context.rb:92:in `with_current_arbre_element'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:49:in `with_current_arbre_element'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:26:in `build_tag'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:39:in `insert_tag'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:14:in `sidebar_section'
activeadmin (1.0.0) lib/active_admin/views/pages/base.rb:132:in `block (2 levels) in build_sidebar'
activeadmin (1.0.0) lib/active_admin/views/pages/base.rb:131:in `collect'
activeadmin (1.0.0) lib/active_admin/views/pages/base.rb:131:in `block in build_sidebar'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:31:in `block in build_tag'
arbre (1.1.1) lib/arbre/context.rb:92:in `with_current_arbre_element'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:49:in `with_current_arbre_element'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:26:in `build_tag'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:39:in `insert_tag'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:14:in `div'
activeadmin (1.0.0) lib/active_admin/views/pages/base.rb:130:in `build_sidebar'
activeadmin (1.0.0) lib/active_admin/views/pages/base.rb:78:in `block in build_page_content'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:31:in `block in build_tag'
arbre (1.1.1) lib/arbre/context.rb:92:in `with_current_arbre_element'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:49:in `with_current_arbre_element'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:26:in `build_tag'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:39:in `insert_tag'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:14:in `div'
activeadmin (1.0.0) lib/active_admin/views/pages/base.rb:76:in `build_page_content'
activeadmin (1.0.0) lib/active_admin/views/pages/base.rb:54:in `block (2 levels) in build_page'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:31:in `block in build_tag'
arbre (1.1.1) lib/arbre/context.rb:92:in `with_current_arbre_element'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:49:in `with_current_arbre_element'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:26:in `build_tag'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:39:in `insert_tag'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:14:in `div'
activeadmin (1.0.0) lib/active_admin/views/pages/base.rb:50:in `block in build_page'
arbre (1.1.1) lib/arbre/context.rb:92:in `with_current_arbre_element'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:49:in `with_current_arbre_element'
activeadmin (1.0.0) lib/active_admin/views/pages/base.rb:49:in `build_page'
activeadmin (1.0.0) lib/active_admin/views/pages/base.rb:10:in `build'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:30:in `block in build_tag'
arbre (1.1.1) lib/arbre/context.rb:92:in `with_current_arbre_element'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:26:in `build_tag'
arbre (1.1.1) lib/arbre/element/builder_methods.rb:39:in `insert_tag'
activeadmin (1.0.0) app/views/active_admin/resource/index.html.arb:2:in `block in ___sers_lancecoe__rvm_gems_ruby_______gems_activeadmin_______app_views_active_admin_resource_index_html_arb___218697264684546928_70170958353700'
arbre (1.1.1) lib/arbre/context.rb:45:in `instance_eval'
arbre (1.1.1) lib/arbre/context.rb:45:in `initialize'
activeadmin (1.0.0) app/views/active_admin/resource/index.html.arb:1:in `new'
activeadmin (1.0.0) app/views/active_admin/resource/index.html.arb:1:in `___sers_lancecoe__rvm_gems_ruby_______gems_activeadmin_______app_views_active_admin_resource_index_html_arb___218697264684546928_70170958353700'
actionview (4.2.0) lib/action_view/template.rb:145:in `block in render'
activesupport (4.2.0) lib/active_support/notifications.rb:166:in `instrument'
actionview (4.2.0) lib/action_view/template.rb:333:in `instrument'
actionview (4.2.0) lib/action_view/template.rb:143:in `render'
actionview (4.2.0) lib/action_view/renderer/template_renderer.rb:54:in `block (2 levels) in render_template'
actionview (4.2.0) lib/action_view/renderer/abstract_renderer.rb:39:in `block in instrument'
activesupport (4.2.0) lib/active_support/notifications.rb:164:in `block in instrument'
activesupport (4.2.0) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (4.2.0) lib/active_support/notifications.rb:164:in `instrument'
actionview (4.2.0) lib/action_view/renderer/abstract_renderer.rb:39:in `instrument'
actionview (4.2.0) lib/action_view/renderer/template_renderer.rb:53:in `block in render_template'
actionview (4.2.0) lib/action_view/renderer/template_renderer.rb:61:in `render_with_layout'
actionview (4.2.0) lib/action_view/renderer/template_renderer.rb:52:in `render_template'
actionview (4.2.0) lib/action_view/renderer/template_renderer.rb:14:in `render'
actionview (4.2.0) lib/action_view/renderer/renderer.rb:42:in `render_template'
actionview (4.2.0) lib/action_view/renderer/renderer.rb:23:in `render'
actionview (4.2.0) lib/action_view/rendering.rb:100:in `_render_template'
actionpack (4.2.0) lib/action_controller/metal/streaming.rb:217:in `_render_template'
actionview (4.2.0) lib/action_view/rendering.rb:83:in `render_to_body'
actionpack (4.2.0) lib/action_controller/metal/rendering.rb:32:in `render_to_body'
actionpack (4.2.0) lib/action_controller/metal/renderers.rb:37:in `render_to_body'
actionpack (4.2.0) lib/abstract_controller/rendering.rb:25:in `render'
actionpack (4.2.0) lib/action_controller/metal/rendering.rb:16:in `render'
actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:41:in `block (2 levels) in render'
activesupport (4.2.0) lib/active_support/core_ext/benchmark.rb:12:in `block in ms'
/Users/lancecoe/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/benchmark.rb:308:in `realtime'
activesupport (4.2.0) lib/active_support/core_ext/benchmark.rb:12:in `ms'
actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:41:in `block in render'
actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:84:in `cleanup_view_runtime'
activerecord (4.2.0) lib/active_record/railties/controller_runtime.rb:25:in `cleanup_view_runtime'
actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:40:in `render'
responders (2.4.0) lib/action_controller/responder.rb:238:in `default_render'
responders (2.4.0) lib/action_controller/responder.rb:170:in `to_html'
responders (2.4.0) lib/responders/flash_responder.rb:107:in `to_html'
responders (2.4.0) lib/action_controller/responder.rb:163:in `respond'
responders (2.4.0) lib/action_controller/responder.rb:156:in `call'
responders (2.4.0) lib/action_controller/respond_with.rb:211:in `respond_with'
inherited_resources (1.7.2) lib/inherited_resources/actions.rb:7:in `index'
activeadmin (1.0.0) lib/active_admin/resource_controller/streaming.rb:12:in `index'
actionpack (4.2.0) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
actionpack (4.2.0) lib/abstract_controller/base.rb:198:in `process_action'
actionpack (4.2.0) lib/action_controller/metal/rendering.rb:10:in `process_action'
actionpack (4.2.0) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
activesupport (4.2.0) lib/active_support/callbacks.rb:117:in `call'
activesupport (4.2.0) lib/active_support/callbacks.rb:151:in `block in halting_and_conditional'
activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
activesupport (4.2.0) lib/active_support/callbacks.rb:234:in `block in halting'
activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
activesupport (4.2.0) lib/active_support/callbacks.rb:92:in `_run_callbacks'
activesupport (4.2.0) lib/active_support/callbacks.rb:734:in `_run_process_action_callbacks'
activesupport (4.2.0) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (4.2.0) lib/abstract_controller/callbacks.rb:19:in `process_action'
actionpack (4.2.0) lib/action_controller/metal/rescue.rb:29:in `process_action'
actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
activesupport (4.2.0) lib/active_support/notifications.rb:164:in `block in instrument'
activesupport (4.2.0) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (4.2.0) lib/active_support/notifications.rb:164:in `instrument'
actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
actionpack (4.2.0) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
activerecord (4.2.0) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (4.2.0) lib/abstract_controller/base.rb:137:in `process'
actionview (4.2.0) lib/action_view/rendering.rb:30:in `process'
actionpack (4.2.0) lib/action_controller/metal.rb:195:in `dispatch'
actionpack (4.2.0) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
actionpack (4.2.0) lib/action_controller/metal.rb:236:in `block in action'
actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:73:in `dispatch'
actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:42:in `serve'
actionpack (4.2.0) lib/action_dispatch/journey/router.rb:43:in `block in serve'
actionpack (4.2.0) lib/action_dispatch/journey/router.rb:30:in `each'
actionpack (4.2.0) lib/action_dispatch/journey/router.rb:30:in `serve'
actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:802:in `call'
warden (1.2.7) lib/warden/manager.rb:36:in `block in call'
warden (1.2.7) lib/warden/manager.rb:35:in `catch'
warden (1.2.7) lib/warden/manager.rb:35:in `call'
rack (1.6.8) lib/rack/etag.rb:24:in `call'
rack (1.6.8) lib/rack/conditionalget.rb:25:in `call'
rack (1.6.8) lib/rack/head.rb:13:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/flash.rb:260:in `call'
rack (1.6.8) lib/rack/session/abstract/id.rb:225:in `context'
rack (1.6.8) lib/rack/session/abstract/id.rb:220:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/cookies.rb:560:in `call'
activerecord (4.2.0) lib/active_record/query_cache.rb:36:in `call'
activerecord (4.2.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:647:in `call'
activerecord (4.2.0) lib/active_record/migration.rb:378:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
activesupport (4.2.0) lib/active_support/callbacks.rb:88:in `_run_callbacks'
activesupport (4.2.0) lib/active_support/callbacks.rb:734:in `_run_call_callbacks'
activesupport (4.2.0) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (4.2.0) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/reloader.rb:73:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/remote_ip.rb:78:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
web-console (2.3.0) lib/web_console/middleware.rb:28:in `block in call'
web-console (2.3.0) lib/web_console/middleware.rb:18:in `catch'
web-console (2.3.0) lib/web_console/middleware.rb:18:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
railties (4.2.0) lib/rails/rack/logger.rb:38:in `call_app'
railties (4.2.0) lib/rails/rack/logger.rb:20:in `block in call'
activesupport (4.2.0) lib/active_support/tagged_logging.rb:68:in `block in tagged'
activesupport (4.2.0) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (4.2.0) lib/active_support/tagged_logging.rb:68:in `tagged'
railties (4.2.0) lib/rails/rack/logger.rb:20:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/request_id.rb:21:in `call'
rack (1.6.8) lib/rack/methodoverride.rb:22:in `call'
rack (1.6.8) lib/rack/runtime.rb:18:in `call'
activesupport (4.2.0) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
rack (1.6.8) lib/rack/lock.rb:17:in `call'
actionpack (4.2.0) lib/action_dispatch/middleware/static.rb:113:in `call'
rack (1.6.8) lib/rack/sendfile.rb:113:in `call'
railties (4.2.0) lib/rails/engine.rb:518:in `call'
railties (4.2.0) lib/rails/application.rb:164:in `call'
rack (1.6.8) lib/rack/lock.rb:17:in `call'
rack (1.6.8) lib/rack/content_length.rb:15:in `call'
rack (1.6.8) lib/rack/handler/webrick.rb:88:in `service'
/Users/lancecoe/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/webrick/httpserver.rb:140:in `service'
/Users/lancecoe/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/webrick/httpserver.rb:96:in `run'
/Users/lancecoe/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/webrick/server.rb:296:in `block in start_thread'
Hi,
How do you create a valid factory for models with actable
?
class MyApp::Product < ApplicationRecord
actable inverse_of: :pen
end
class MyApp::Pen < ApplicationRecord
acts_as :product, class_name: 'MyApp::Product'
end
This is what my factory looks like.
FactoryGirl.define do
factory :product, class: 'MyApp::Product' do
name { FFaker::Name.name }
end
end
And I'm getting the following error when running FactoryGirl.lint
Validation failed: Actable must exist (ActiveRecord::RecordInvalid)
When I touch the object it only affects the super not the object itself
[2] pry(main)> Fund.first.touch
Fund Load (0.4ms) SELECT `funds`.* FROM `funds` ORDER BY `funds`.`id` ASC LIMIT 1
Asset Load (0.5ms) SELECT `assets`.* FROM `assets` WHERE `assets`.`actable_type` = 'Fund' AND `assets`.`actable_id` = 701
(0.2ms) BEGIN
SQL (0.5ms) UPDATE `assets` SET `assets`.`updated_at` = '2017-04-20 12:51:10' WHERE `assets`.`id` = 1
(3.8ms) COMMIT
=> true
[3] pry(main)> ap Fund.first.updated_at
Fund Load (0.7ms) SELECT `funds`.* FROM `funds` ORDER BY `funds`.`id` ASC LIMIT 1
Asset Load (0.8ms) SELECT `assets`.* FROM `assets` WHERE `assets`.`actable_type` = 'Fund' AND `assets`.`actable_id` = 701
Fri, 07 Apr 2017 18:00:17 BRT -03:00
=> nil
[4] pry(main)> ap Fund.first.asset.updated_at
Fund Load (0.7ms) SELECT `funds`.* FROM `funds` ORDER BY `funds`.`id` ASC LIMIT 1
Asset Load (0.7ms) SELECT `assets`.* FROM `assets` WHERE `assets`.`actable_type` = 'Fund' AND `assets`.`actable_id` = 701
Thu, 20 Apr 2017 09:51:10 BRT -03:00
While on Rails 5.1.X
and active_recrd-acts_as
on 4.0.3
, the exists?
method fails. The generated SQL does not JOIN the products table. However, where
does work.
Same behavior on Rails 6.1.7
and active_record-acts_as (5.1.0)
as well.
5.1.2
Product.exists?(name: "hi")
- works as intendedBook.exists?(name: "hi")
- fails (see output below)Book.where(name: "hi")
- works howeverLoading development environment (Rails 5.1.2)
>> Product.exists?(name: "hi")
Product Exists (1.7ms) SELECT 1 AS one FROM "products" WHERE "products"."name" = $1 LIMIT $2 [["name", "hi"], ["LIMIT", 1]]
=> false
>> Book.exists?(name: "hi")
Book Exists (2.3ms) SELECT 1 AS one FROM "books" LIMIT $1 [["LIMIT", 1]]
Book Exists (1.0ms) SELECT 1 AS one FROM "books" WHERE "products"."name" = $1 LIMIT $2 [["name", "hi"], ["LIMIT", 1]]
Traceback (most recent call last):
1: from (irb):2
ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR: missing FROM-clause entry for table "products")
LINE 1: SELECT 1 AS one FROM "books" WHERE "products"."name" = $1 L...
^
: SELECT 1 AS one FROM "books" WHERE "products"."name" = $1 LIMIT $2
>> Book.where(name: "hi")
SQL (2.6ms) SELECT "books"."id" AS t0_r0, "books"."author" AS t0_r1, "books"."created_at" AS t0_r2, "books"."updated_at" AS t0_r3, "products"."id" AS t1_r0, "products"."name" AS t1_r1, "products"."price" AS t1_r2, "products"."created_at" AS t1_r3, "products"."updated_at" AS t1_r4, "products"."actable_type" AS t1_r5, "products"."actable_id" AS t1_r6 FROM "books" LEFT OUTER JOIN "products" ON "products"."actable_id" = "books"."id" AND "products"."actable_type" = $1 WHERE "products"."name" = $2 LIMIT $3 [["actable_type", "Book"], ["name", "hi"], ["LIMIT", 11]]
=> #<ActiveRecord::Relation []>
On Rails 5.0.7.2
, the .exists?
works fine:
Loading development environment (Rails 5.0.7.2)
>> Book.exists?(name: "hello")
Book Exists (0.0ms) SELECT 1 AS one FROM "books" LEFT OUTER JOIN "products" ON "products"."actable_id" = "books"."id" AND "products"."actable_type" = ? LIMIT ? [["actable_type", "Book"], ["LIMIT", 1]]
Book Exists (0.0ms) SELECT 1 AS one FROM "books" LEFT OUTER JOIN "products" ON "products"."actable_id" = "books"."id" AND "products"."actable_type" = ? WHERE "products"."name" = ? LIMIT ? [["actable_type", "Book"], ["name", "hello"], ["LIMIT", 1]]
=> false
>> exit
Working with two name spaced models. The first, the parent model
# model
class Rezzable::WebObject < ApplicationRecord
actable inverse_of: :pinger
belongs_to :user
end
#schema
create_table "rezzable_web_objects", id: :serial, force: :cascade do |t|
t.integer "actable_id"
t.string "actable_type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
And the child model looks like this
#model
class Rezzable::Pinger < ApplicationRecord
acts_as :web_object, class_name: 'Rezzable::WebObject'
end
#schema
create_table "rezzable_pingers", id: :serial, force: :cascade do |t|
t.string "reply"
end
Then i get a the following error when I try to create a pinger in the console. Everyting works fine with the Pen and Product as shown in the documtation.
2.3.4 :001 > p = FactoryBot.build :rezzable_pinger
(0.3ms) BEGIN
Rezzable::WebObject Exists (1.2ms) SELECT 1 AS one FROM "rezzable_web_objects" WHERE "rezzable_web_objects"."object_key" = $1 LIMIT $2 [["object_key", "3d18ec86-3aca-45a3-b4f9-8c7101abccbf"], ["LIMIT", 1]]
Rezzable::WebObject Exists (0.5ms) SELECT 1 AS one FROM "rezzable_web_objects" WHERE "rezzable_web_objects"."url" = $1 LIMIT $2 [["url", "http://sim27868.agni.lindenlab.com:12043/cap/3d18ec86-3aca-45a3-b4f9-8c7101abccbf"], ["LIMIT", 1]]
Rezzable::WebObject Exists (0.5ms) SELECT 1 AS one FROM "rezzable_web_objects" WHERE "rezzable_web_objects"."secure_url" = $1 LIMIT $2 [["secure_url", "https://sim27868.agni.lindenlab.com:12043/cap/3d18ec86-3aca-45a3-b4f9-8c7101abccbf"], ["LIMIT", 1]]
SQL (1.6ms) INSERT INTO "rezzable_web_objects" ("object_key", "object_name", "region", "position", "url", "secure_url", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["object_key", "3d18ec86-3aca-45a3-b4f9-8c7101abccbf"], ["object_name", "Carry pinterest viral"], ["region", "Aliquid"], ["position", "(181.441251, 155.305379, 245.072744)"], ["url", "http://sim27868.agni.lindenlab.com:12043/cap/3d18ec86-3aca-45a3-b4f9-8c7101abccbf"], ["secure_url", "https://sim27868.agni.lindenlab.com:12043/cap/3d18ec86-3aca-45a3-b4f9-8c7101abccbf"], ["created_at", "2018-01-27 18:47:34.258067"], ["updated_at", "2018-01-27 18:47:34.258067"]]
(4.5ms) COMMIT
ActiveRecord::InverseOfAssociationNotFoundError: Could not find the inverse association for actable (:pinger in Rezzable::Pinger)
from (eval):1:in `web_object'
from (irb):1
It seems to me its a problem with the namespaces, but I thought I followed the method in the documentation. Any thoughts? Thanks in advance.
Ruby 3.0 support is still unreleased. We're upgrading from Ruby 2.7 to Ruby 3.0 shortly so that'd sure be helpful.
Any way we can get a new version released?
Here is the version on RubyGems.org but I can't find a diff.
Is it official?
Did I miss something?
rails 5.2.8.1
active_record-acts_as 4.0.3
Note: Higher versions of rails don't seem to have this issue (e.g. rails 6.1.7)
# schema.rb
ActiveRecord::Schema.define(version: 2023_10_25_160214) do
create_table "books", force: :cascade do |t|
t.string "author"
t.string "external_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "products", force: :cascade do |t|
t.integer "price"
t.string "actable_type"
t.integer "actable_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["actable_type", "actable_id"], name: "index_products_on_actable_type_and_actable_id"
end
end
I'm running into an error where when chaining the create_with
and find_or_create_by!
methods.
>> b = Book.create_with(author: "martin").find_or_create_by!(external_id: "1231236")
Book Load (0.1ms) SELECT "books".* FROM "books" WHERE "books"."external_id" = ? LIMIT ? [["external_id", "1231236"], ["LIMIT", 1]]
Traceback (most recent call last):
2: from (irb):5
1: from (irb):6:in `rescue in irb_binding'
NoMethodError (undefined method `include?' for :author:Symbol)
I think I've traced it down to this call in the scope_for_create
method
My reasoning for thinking this is that Rails 5.2.8.1 seems to stringifies their keys in the scope_for_create
method https://github.com/rails/rails/blob/8030cff808657faa44828de001cd3b80364597de/activerecord/lib/active_record/relation.rb#L468-L468
So I overrode the scope_for_create
method from the acts_as
gem and it seems to work fine
module ActiveRecord
module ActsAs
module ScopeForCreate
def scope_for_create(attributes = nil)
unless acting_as?
if Gem::Dependency.new("", ">= 5.2.1", "< 5.2.2").match?("", ActiveRecord.version) # rubocop:disable Style/GuardClause
return super(attributes)
else
return super()
end
end
scope = respond_to?(:values_for_create) ? values_for_create(attributes) : where_values_hash
scope.merge!(where_values_hash(acting_as_model.table_name))
scope.merge!(attributes) if attributes
scope.merge(create_with_value.stringify_keys) # stringify keys here
end
end
end
end
I'll be upgrading to rails 6 eventually (where this issue doesn't exist), but in the meantime, is overriding this one line appropriate? Or could it cause potential issues with other queries?
Update: As an alternative solution I found that you can use a hash in the create_with
like Book.create_with("author" => "martin").find_or_create_by!(external_id: "1231236")
Rails 5.1 is not yet supported since one spec fails: https://travis-ci.org/krautcomputing/active_record-acts_as/jobs/258840517
I have tried to dig into ActiveRecord and find out what changed from 5.0 to 5.1 and how to fix it but failed. If anyone with more knowledge of the ActiveRecord internals could have a look, that'd be great! ๐ฅ
I created a separate branch for Rails 5.1 compatibility.
In the examples:
store = Store.create
store.products << Pen.create
store.products.first
# => #<Product: ...>
But this saves the Pen
on line 2. What if I want to attach but not yet save it, as I want to add additional attributes? The <<
method will save whatever you pass to it.
In the normal, non-inheritence world, I would do:
store = Store.create
product = store.products.build
# ...
product.save
But if I'm using inheritence, if I want it to be a Pen
, I've found this works:
store = Store.create
product = store.products.build(actable: Pen.new)
# ...
product.save
Maybe there is already a better way. If not, I would propose something like this:
store = Store.create
product = store.products.build_pen
# ...
product.save
I am getting this error
ActiveRecord::HasManyThroughOrderError: Cannot have a has_many :through association 'Store#fulfillment' which goes through 'Store#service' before the through association is defined.
I have this in models
class Store < ApplicationRecord
acts_as :service
has_one :fulfillment, class_name: 'Billing::Fulfillment', through: :service, dependent: :destroy
end
class Service < ApplicationRecord
actable
end
the has_one association (has_one :store is build by gem itself), I don't know what I am doing wrong. It works fine with rails 4.2 this issue is occurring when I Upgrade to rails 5.1
Pen.find(i)
will not necessarily be the same as Product.find(i).specific
as the pens
and products
tables have different IDs. If I want to:
Pen
sProduct
IDPen
objectsIs there a better way to do this than something like Pen.find_by(products: {id: i})
?
This doesn't happen with 3.1.0. The attributes are not being merged into the new object.
The problem appears to be in scope_for_create
. I'm not an expert in the internals of rails, but perhaps something like this might be safer?
module ScopeForCreate
def scope_for_create(attributes = nil)
return super unless acting_as?
scope = respond_to?(:values_for_create) ? values_for_create(attributes) : where_values_hash
scope.merge!(where_values_hash(acting_as_model.table_name))
scope.merge!(attributes) if attributes
scope.merge(create_with_value)
end
end
Hi. I have an issue with a very basic use case.
I just created two models as documented on README. Product and Pen
class CreateProducts < ActiveRecord::Migration[5.2]
def change
create_table :products do |t|
t.actable
t.string :name
t.integer :price
t.timestamps
end
end
end
And Pen:
class CreatePens < ActiveRecord::Migration[5.2]
def change
create_table :pens do |t|
t.string :color
end
end
end
Then in models:
class Product < ApplicationRecord
actable
end
class Pen < ApplicationRecord
acts_as :product
end
But when I try to create a Product I get following error:
2.5.1 :004 > x = Product.new(name: "Product", price: 5)
=> #<Product id: nil, actable_type: nil, actable_id: nil, name: "Product", price: 5, created_at: nil, updated_at: nil>
2.5.1 :005 > x.valid?
=> false
2.5.1 :006 > x.errors.messages
=> {:actable=>["must exist"]}
2.5.1 :007 >
What am I wrong?
When creating a Pen, everything is ok. But I need create a Product!!! Please help.
The actables
class method does not restrict based on actable type, so will actually return incorrect results.
For example, consider the following structure (using Product (base), Pen and Book from the Readme)
Pen.create(name: 'Parker', price: 1.0, color: 'Black')
Book.create(name: 'Mystery', price: 1.0, color: 'Black')
Pen.where(color: 'Black').actables # => returns 2 products, including also the book!
Hi,
When using this gem together with globalize
gem, I'm getting the following error when using .where
and .order
on translated column name.
class MyApp::Product < ApplicationRecord
actable inverse_of: :actable
translates :description, :name
end
class MyApp::Pen < ApplicationRecord
acts_as :product, class_name: 'MyApp::Product'
end
The following active record query methods will fail:
MyApp::Product.where(name: 'pen') or MyApp::Product.order(name: :asc)
ERROR: column my_app_products.name does not exist
Because of globalize
, name
column is in the translation table of product. Instead, it should be looking in my_app_product_translations
I know below is not the best code, but just fiddling around seems to take care of the .where
issue.
translated_acts_as_opts = acts_as_opts.select{ |k,v| acting_as_model.translated? k }
acts_as_opts.reject!{ |k,v| acting_as_model.translated? k }
if acts_as_opts.any?
opts[acting_as_model.table_name] = acts_as_opts
end
if translated_acts_as_opts.any?
opts[acting_as_model.translations_table_name] = translated_acts_as_opts
end
My question is how do you override the .order
method? Do you have any plan on making this gem compatible with globalize
gem?
This will require a heavy refactoring of the gem. while trying to maintain compatibility with existing applications.
To make this backward compatible, the first call to acts_as
will be tagged as main
, while other acts_as
will have to have their attributes prefixed to avoid collisions.
Migrate to Github Actions.
Hi friends! I've opened a pull request #3
Our problem:
We have some legacy infrastructure that needs datetime
attributes on our submodels, in order to support that, we were wondering if we could support both cases? I'm confident my change will check for both cases and bubble them up to the proper submodel or supermodel.
I've also added some tests for sanity.
I am in the process of upgrading to Rails 5.1.6 and have run into an issue querying using relational objects declared in belongs_to
relationships.
We were using the rails51 branch and everything was working correctly until last week wafter upgrading to the 3.0.0
release. This commit replaced the check for attribute_method
; however it causes queries that try to reference belongs_to
members to use the incorrect table name.
E.g. If I define a Rocket
that acts_as :product
who belongs to a StarShip
and try to query Rockets
by their Starship
; they query uses the actable
table name instead of the Rocket
table name:
Failure/Error: expect(Rocket.where(star_ship: star_ship)).to(eq(star_ship.rockets))
ActiveRecord::StatementInvalid:
SQLite3::SQLException: no such column: products.star_ship: SELECT "rockets"."id" AS t0_r0, "rockets"."star_ship_id" AS t0_r1, "products"."id" AS t1_r0, "products"."name" AS t1_r1, "products"."price" AS t1_r2, "products"."store_id" AS t1_r3, "products"."settings" AS t1_r4, "products"."created_at" AS t1_r5, "products"."updated_at" AS t1_r6, "products"."actable_type" AS t1_r7, "products"."actable_id" AS t1_r8 FROM "rockets" LEFT OUTER JOIN "products" ON "products"."actable_id" = "rockets"."id" AND "products"."actable_type" = ? WHERE "products"."star_ship" = ?
The query should instead be:
SELECT "rockets"."id" AS t0_r0, "rockets"."star_ship_id" AS t0_r1, "products"."id" AS t1_r0, "products"."name" AS t1_r1, "products"."price" AS t1_r2, "products"."store_id" AS t1_r3, "products"."settings" AS t1_r4, "products"."created_at" AS t1_r5, "products"."updated_at" AS t1_r6, "products"."actable_type" AS t1_r7, "products"."actable_id" AS t1_r8 FROM "rockets" LEFT OUTER JOIN "products" ON "products"."actable_id" = "rockets"."id" AND "products"."actable_type" = ? WHERE "rockets"."star_ship_id" = ?
The relation method actables
(ActsAs::ReflectionsWithActsAs) is not documented in the README (I was about to propose a feature request for this functionality ๐
, I've added a small PR to add it in there).
That aside, actables
seems to only work when the default name of actable
is used (it uses hardcoded where(actable_id: ...)
).
So a configuration like
class Product < ActiveRecord::Base
actable as: :producible
end
class Pen < ActiveRecord::Base
acts_as :product, as: :producible
end
Product.where(price: 0.8).actables
will not work.
I believe to make actables
work with differently named relations, the ActsAs::Relations::ClassMethods
needs to define a way to retrieve the as
parameter, or pass it along somehow. It would also need to define a method on the class instance with the plural of what is passed to the as
. Something along the lines of:
...
singleton_class.module_eval do
include ActsAs::ClassMethods
def <as.to_s.pluralize.to_sym>
acting_as_model.where("#{as}_id" => select(:id))
end
end
I'm afraid I do not quite know how to do that, or I would suggest a pull request myself. However, perhaps it is possible for you to add this?
Does this library work with namespace'd models? I've been having issues doing so. Below is a simplified version of my use case:
Migration:
create_table :route_locations do |t|
t.timestamps
t.actable as: :locatable
t.string :longitude
t.string :latitude
end
# child of `routes_locations`
create_table :route_named_locations do |t|
t.string :name
end
Models:
class Route::Location < ApplicationRecord
actable as: :locatable
end
class Route::NamedLocation < ApplicationRecord
acts_as :location, as: :locatable
end
When running Route::NamedLocation.all
via rails console I get the following error:
NameError: uninitialized constant Location
which makes sense since I need Route::Location
not just Location
but I am unable to define it with the namespace. I've tried the following:
acts_as :route_location, as: :locatable
NameError: uninitialized constant RouteLocation
acts_as Route::Location, as: :locatable
TypeError: Route::Location(...) is not a symbol nor a string
acts_as 'Route::Location', as: :locatable
ArgumentError: association names must be a Symbol
acts_as :'Route::Location', as: :locatable
NameError: undefined local variable or method 'build_Route' for #<Module:0x000000035bde18>
Hello,
I'm trying to access scopes/class_methods defined in the "parent", but from the child but i'm getting NoMethodError: undefined method "scope_name"
For instance : Product
has a published
scope. and Pen
is acting_as
a Product
. So I'm trying to call : Pen.published
. and it does not work with the error mentionned above.
I'm using the latest version of the gem active_record-acts_as (3.0.1)
and rails 5.2.0
Is this feature implemented in the gem?
Thank you in advance
Hi, Thank you for creating this gem, its really useful,
I currently updating the ruby version to 2.7 in a project, noticed that the master has the changes needed for warnings given with ruby 2.7, could you bump the version with the changes please
Thanks in advance
I have a class which needs multiple parent associations. The acts_as class is set up to associate these of different keys, however it is only building the last association declared.
class MyObject < ApplicationRecord
acts_as :maintainable_resource, class_name: "Maintenance::MaintainableResource", as: :maintainable, dependent: :destroy
acts_as :schedulable_resource, class_name: "Schedule::SchedulableResource", as: :schedulable, dependent: :destroy
end
This call only builds a ScheulableResource, not a MaintainableResource. Switching the order results in the opposite.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.