Back to list
radioactive-labs

plutonium-definition-query

by radioactive-labs

Build production-ready Rails apps in minutes, not days. Convention-driven, fully customizable, AI-ready.

52🍴 7📅 Jan 23, 2026

SKILL.md


name: plutonium-definition-query description: Configure search, filters, scopes, and sorting for Plutonium resources

Definition Query

Configure how users can search, filter, and sort resource collections.

Overview

class PostDefinition < ResourceDefinition
  # Search - global text search
  search do |scope, query|
    scope.where("title ILIKE ?", "%#{query}%")
  end

  # Filters - dropdown filter panel
  filter :title, with: :text, predicate: :contains
  filter :status, with: :select, choices: %w[draft published archived]
  filter :published, with: :boolean
  filter :created_at, with: :date_range
  filter :category, with: :association

  # Scopes - quick filter buttons
  scope :published
  scope :draft

  # Sorting - sortable columns
  sort :title
  sort :created_at

  # Default sort
  default_sort :created_at, :desc
end

Define global search across fields:

# Single field
search do |scope, query|
  scope.where("title ILIKE ?", "%#{query}%")
end

# Multiple fields
search do |scope, query|
  scope.where(
    "title ILIKE :q OR content ILIKE :q OR author_name ILIKE :q",
    q: "%#{query}%"
  )
end

# With associations
search do |scope, query|
  scope.joins(:author).where(
    "posts.title ILIKE :q OR users.name ILIKE :q",
    q: "%#{query}%"
  ).distinct
end

# Split search terms
search do |scope, query|
  terms = query.split(/\s+/)
  terms.reduce(scope) do |current_scope, term|
    current_scope.where("title ILIKE ?", "%#{term}%")
  end
end

Filters

Plutonium provides 6 built-in filter types. Use shorthand symbols or full class names.

Text Filter

String/text filtering with pattern matching.

# Shorthand (recommended)
filter :title, with: :text, predicate: :contains
filter :status, with: :text, predicate: :eq

# Full class name
filter :title, with: Plutonium::Query::Filters::Text, predicate: :contains

Predicates:

PredicateSQLDescription
:eq= valueExact match (default)
:not_eq!= valueNot equal
:containsLIKE %value%Contains substring
:not_containsNOT LIKE %value%Does not contain
:starts_withLIKE value%Starts with
:ends_withLIKE %valueEnds with
:matchesLIKE valuePattern match (* becomes %)
:not_matchesNOT LIKE valueDoes not match pattern

Boolean Filter

True/false filtering for boolean columns.

# Basic
filter :active, with: :boolean

# Custom labels
filter :published, with: :boolean, true_label: "Published", false_label: "Draft"

Renders a select dropdown with "All", true label ("Yes"), and false label ("No").

Date Filter

Single date filtering with comparison predicates.

filter :created_at, with: :date, predicate: :gteq  # On or after
filter :due_date, with: :date, predicate: :lt      # Before
filter :published_at, with: :date, predicate: :eq  # On exact date

Predicates:

PredicateDescription
:eqOn this date (default)
:not_eqNot on this date
:ltBefore date
:lteqOn or before date
:gtAfter date
:gteqOn or after date

Date Range Filter

Filter between two dates (from/to).

# Basic
filter :created_at, with: :date_range

# Custom labels
filter :published_at, with: :date_range,
  from_label: "Published from",
  to_label: "Published to"

Renders two date pickers. Both are optional - users can filter with just "from" or just "to".

Select Filter

Filter from predefined choices.

# Static choices (array)
filter :status, with: :select, choices: %w[draft published archived]

# Dynamic choices (proc)
filter :category, with: :select, choices: -> { Category.pluck(:name) }

# Multiple selection
filter :tags, with: :select, choices: %w[ruby rails js], multiple: true

Association Filter

Filter by associated record.

# Basic - infers Category class from :category key
filter :category, with: :association

# Explicit class
filter :author, with: :association, class_name: User

# Multiple selection
filter :tags, with: :association, class_name: Tag, multiple: true

Renders a resource select dropdown. Converts filter key to foreign key (:category -> :category_id).

Custom Filters

Custom Filter Class

class PriceRangeFilter < Plutonium::Query::Filter
  def apply(scope, min: nil, max: nil)
    scope = scope.where("price >= ?", min) if min.present?
    scope = scope.where("price <= ?", max) if max.present?
    scope
  end

  def customize_inputs
    input :min, as: :number
    input :max, as: :number
    field :min, placeholder: "Min price..."
    field :max, placeholder: "Max price..."
  end
end

# Use in definition
filter :price, with: PriceRangeFilter

Scopes

Scopes appear as quick filter buttons. They reference model scopes.

Basic Usage

class PostDefinition < ResourceDefinition
  scope :published    # Uses Post.published
  scope :draft        # Uses Post.draft
  scope :featured     # Uses Post.featured
end

Inline Scope

Use block syntax with the scope passed as an argument:

scope(:recent) { |scope| scope.where('created_at > ?', 1.week.ago) }
scope(:this_month) { |scope| scope.where(created_at: Time.current.all_month) }

With Controller Context

Inline scopes have access to controller context like current_user:

scope(:mine) { |scope| scope.where(author: current_user) }
scope(:my_team) { |scope| scope.where(team: current_user.team) }

Default Scope

Set a scope as default to apply it when no scope is explicitly selected:

class PostDefinition < ResourceDefinition
  scope :published, default: true  # Applied by default
  scope :draft
  scope :archived
end

When a default scope is set:

  • The default scope is applied on initial page load
  • The default scope button is highlighted (not "All")
  • Clicking "All" shows all records without any scope filter
  • URL without scope param uses the default; URL with ?q[scope]= uses "All"

Sorting

Basic Sorting

sort :title
sort :created_at
sort :view_count

# Multiple at once
sorts :title, :created_at, :view_count

Default Sort

# Field and direction
default_sort :created_at, :desc
default_sort :title, :asc

# Complex sorting with block
default_sort { |scope| scope.order(featured: :desc, created_at: :desc) }

Note: Default sort only applies when no sort params are provided.

URL Parameters

Query parameters are structured under q:

/posts?q[search]=rails
/posts?q[title][query]=widget
/posts?q[status][value]=published
/posts?q[created_at][from]=2024-01-01&q[created_at][to]=2024-12-31
/posts?q[scope]=recent
/posts?q[sort_fields][]=created_at&q[sort_directions][created_at]=desc

Filter Summary Table

TypeSymbolInput ParamsOptions
Text:textquerypredicate:
Boolean:booleanvaluetrue_label:, false_label:
Date:datevaluepredicate:
Date Range:date_rangefrom, tofrom_label:, to_label:
Select:selectvaluechoices:, multiple:
Association:associationvalueclass_name:, multiple:

Complete Example

class ProductDefinition < ResourceDefinition
  # Full-text search
  search do |scope, query|
    scope.where(
      "name ILIKE :q OR description ILIKE :q",
      q: "%#{query}%"
    )
  end

  # Filters
  filter :name, with: :text, predicate: :contains
  filter :status, with: :select, choices: %w[draft active discontinued]
  filter :featured, with: :boolean
  filter :created_at, with: :date_range
  filter :price, with: :date, predicate: :gteq
  filter :category, with: :association

  # Quick scopes
  scope :active, default: true
  scope :featured
  scope(:recent) { |scope| scope.where('created_at > ?', 1.week.ago) }

  # Sortable columns
  sorts :name, :price, :created_at

  # Default sort
  default_sort :created_at, :desc
end

Performance Tips

  1. Add indexes for filtered/sorted columns
  2. Use .distinct when joining associations in search
  3. Consider pg_search for complex full-text search
  4. Limit search fields to indexed columns
  5. Use scopes instead of filters for common queries
  • plutonium-definition - Overview and structure
  • plutonium-definition-fields - Fields, inputs, displays
  • plutonium-definition-actions - Actions and interactions

Score

Total Score

75/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

0/15
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon