Skip to content

Querying for records with specific settings #69

@olliebennett

Description

@olliebennett

The available scopes currently allow querying records which do/do not have settings of a specific type.

How could we retrieve all records where a specific setting matches the supplied value, whether having been explicitly set, or falling back to the "default" configuration? The with_settings_for(:symbol) (for example) only identifies whether the setting is set.

Example: Suppose this gem is used to track the various email delivery options for a user:

# app/models/user.rb
has_settings do |s|
  s.key :email_notifications, defaults: {
    account_updates: 'daily',
    newsletter: true
  }
end
# user controller's `update` action, when user opts in/out of newsletter emails
@user.settings(:email_notifications).newsletter = true # or false

What would be the best way to identify all users who are "opted in" to the newsletter, either explicitly (having set their settings), or by default? The current scopes do not support this.

My (perhaps somewhat ugly!) custom query achieving this is as follows:

@my_users.joins(%(
  LEFT OUTER JOIN settings
  ON  settings.target_type = 'User'
  AND settings.target_id = users.id
))
.where(%(
  (settings.var = 'email_notifications' AND settings.value LIKE '%newsletter: true%')
  OR settings.value IS NULL'
))

The equivalent for retrieving all users who have opted out, is a little simpler:

@my_users.joins(%(
  INNER JOIN settings
  ON  settings.target_type = 'User'
  AND settings.target_id = users.id
))
.where("settings.var = 'email_notifications'")
.where("settings.value LIKE '%newsletter: false%'")

This query retrieves all users which have either not defined their :email_notifications settings at all, or who have defined newsletter = true as above.

Do these sound like valid/useful candidates for new out-of-the-box scopes?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions