Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Common#activity_key_prefix to allow key customization. (In support of STI) #392

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jordonbiondo
Copy link

@jordonbiondo jordonbiondo commented Oct 29, 2024

What?

This PR introduces the activity_key_prefix method in PublicActivity::Common.

This method returns self.class.name by default. The result of this method is used to determine the prefix of activity keys when only an action is provided to create_activity. Example usage below.

class Default < AppModel
  tracked
end

Default.new.create_activity(:foo) # => The activity key is 'default.foo'
class Customized < AppModel
  tracked
  def activity_key_prefix
    'My Custom Key'
  end
end

Customized.new.create_activity(:foo) # => The activity key is 'my_custom_key.foo'

Why?

This change is in support of using single table inheritance. This is not a generalized approach to supporting STI, but it provides a mechanism for users to obtain the behavior necessary for maintaining the same trackable_type, key structure and association queries for parent and child classes.

Below is a demonstration of the current issue preventing simple STI usage and the ability to resolve the issue by overriding activity_key_prefix.

With these models:

class Animal < ActiveRecord::Base
  include PublicActivity::Model
  tracked
end

class Dog < Animal
end

The current behavior is:

Animal.new.create_activity(:foo) # => 
# activity.trackable_type = 'Animal'                      ✅
#            activity.key = 'animal.foo'                  ✅
# animal.activities queries for trackable_type = 'Animal' ✅


Dog.new.create_activity(:foo) # => 
# activity.trackable_type = 'Animal'                         ✅
#            activity.key = 'dog.foo'                        ❌
# animal.activities queries for trackable_type = 'Animal'    ✅

Notice that the activity key is inconsistent with the trackable_type and association. Ideally a generalized solution would exist to support STI in this way, but changing the default behavior would likely break existing implementations somewhere. The ideal approach would be to scan up the ancestry tree to find the ancestor that directly included public activity and use that class name. In the meantime, this PR simple provides a mechanism to implement this behavior on a per-model basis. Like so:

class Animal < ActiveRecord::Base
  include PublicActivity::Model
  tracked

  def activity_prefix_key
    Animal.name
  end
end


# Now:

Dog.new.create_activity(:foo) # activity.trackable_type = 'Animal'                      ✅
                              #            activity.key = 'animal.foo'                  ✅
                              # animal.activities queries for trackable_type = 'Animal' ✅

I realize that my desired STI behavior may not align with others who want to use the child class specific key to do i18n lookups on a child class basis. However, this change will not effect existing implementations, it simply gives users the ability to customize the prefix however they want, if they want.

class Default
  include PublicActivity::Common
end

Default.new.create_activity(:foo) # => The activity key is 'default.foo'

class Customized
  include PublicActivity::Common

  def activity_key_prefix
    "My Custom Key'
  end
end

Customized.new.create_activity(:foo) # => The activity key is 'my_custom_key.foo'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant