Skip to content

Instantly share code, notes, and snippets.

@jcuervo
Last active June 26, 2024 00:26
Show Gist options
  • Select an option

  • Save jcuervo/e9e11e815951933a3e36fa943387831d to your computer and use it in GitHub Desktop.

Select an option

Save jcuervo/e9e11e815951933a3e36fa943387831d to your computer and use it in GitHub Desktop.

Revisions

  1. jcuervo revised this gist Jun 26, 2024. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions enums_for_scoping.md
    Original file line number Diff line number Diff line change
    @@ -32,7 +32,6 @@ class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    scope :recent_pending, -> { pending.where('created at > ?', Date.current) }
    end
    recent_pending_tasks = Task.recent_pending
    ```

    @@ -51,7 +50,6 @@ class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    scope :not_archived, -> { where.not(status: archived) }
    end
    workable_tasks = Task.not_archived
    ```

  2. jcuervo revised this gist Jun 26, 2024. 1 changed file with 0 additions and 3 deletions.
    3 changes: 0 additions & 3 deletions enums_for_scoping.md
    Original file line number Diff line number Diff line change
    @@ -30,7 +30,6 @@ We can build custom scopes for each enum values which in turn provides complex b
    ```
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    scope :recent_pending, -> { pending.where('created at > ?', Date.current) }
    end
    @@ -50,7 +49,6 @@ Enums are often used to manage state transitions. This is very useful for workfl
    ```
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    scope :not_archived, -> { where.not(status: archived) }
    end
    @@ -74,7 +72,6 @@ Enums can be combined with ActiveRecord callbacks to perform actions based on th
    ```
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    after_update :notify_managers, if: status_changed?
    def notify_managers
  3. jcuervo revised this gist Jun 26, 2024. No changes.
  4. jcuervo revised this gist Jun 26, 2024. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions enums_for_scoping.md
    Original file line number Diff line number Diff line change
    @@ -30,6 +30,7 @@ We can build custom scopes for each enum values which in turn provides complex b
    ```
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    scope :recent_pending, -> { pending.where('created at > ?', Date.current) }
    end
    @@ -49,8 +50,10 @@ Enums are often used to manage state transitions. This is very useful for workfl
    ```
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    scope :not_archived, -> { where.not(status: archived) }
    end
    workable_tasks = Task.not_archived
    ```

    @@ -71,6 +74,7 @@ Enums can be combined with ActiveRecord callbacks to perform actions based on th
    ```
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    after_update :notify_managers, if: status_changed?
    def notify_managers
  5. jcuervo revised this gist Jun 26, 2024. 1 changed file with 1 addition and 5 deletions.
    6 changes: 1 addition & 5 deletions enums_for_scoping.md
    Original file line number Diff line number Diff line change
    @@ -30,7 +30,6 @@ We can build custom scopes for each enum values which in turn provides complex b
    ```
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    scope :recent_pending, -> { pending.where('created at > ?', Date.current) }
    end
    @@ -50,10 +49,8 @@ Enums are often used to manage state transitions. This is very useful for workfl
    ```
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    scope :not_archived, -> { where.not(status: archived) }
    end
    workable_tasks = Task.not_archived
    ```

    @@ -74,9 +71,8 @@ Enums can be combined with ActiveRecord callbacks to perform actions based on th
    ```
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    after_update :notify_managers, if: status_changed?
    def notify_managers
    # send notifications to managers about task changes
    end
  6. jcuervo revised this gist Jun 21, 2024. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions enums_for_scoping.md
    Original file line number Diff line number Diff line change
    @@ -31,7 +31,7 @@ We can build custom scopes for each enum values which in turn provides complex b
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    scope :recent_pending, -> { pending.where( 'created at > ?', Date.current) }
    scope :recent_pending, -> { pending.where('created at > ?', Date.current) }
    end
    recent_pending_tasks = Task.recent_pending
    @@ -51,7 +51,7 @@ Enums are often used to manage state transitions. This is very useful for workfl
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    scope :not_archived, -> {where.not (status: archived }
    scope :not_archived, -> { where.not(status: archived) }
    end
    workable_tasks = Task.not_archived
    @@ -75,7 +75,7 @@ Enums can be combined with ActiveRecord callbacks to perform actions based on th
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    after_update:notify_managers, if: status_changed?
    after_update :notify_managers, if: status_changed?
    def notify_managers
    # send notifications to managers about task changes
  7. jcuervo revised this gist Jun 21, 2024. 1 changed file with 30 additions and 30 deletions.
    60 changes: 30 additions & 30 deletions enums_for_scoping.md
    Original file line number Diff line number Diff line change
    @@ -14,74 +14,74 @@ Enums make sure that only the predefined values can be used for the specified at

    Let's walk though several powerful features of enums:

    1. Query methods.
    **1. Query methods.**
    The generated query methods for each value makes querying based on the enum's state very straightforward. With the code above, we can write the query methods like:

    ```
    pending_tasks = Task.pending
    active_tasks = Task.active
    completed_tasks = Task.completed
    paused_tasks = Task.paused

    ```

    Scopes for enums.
    **2. Scopes for enums.**
    We can build custom scopes for each enum values which in turn provides complex but readable queries.

    ```
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4}

    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    scope :recent_pending, -> { pending. where ( 'created at > ?', Date.current) }
    scope :recent_pending, -> { pending.where( 'created at > ?', Date.current) }
    end

    recent_pending_tasks = Task.recent_pending

    ```

    Conditional queries.
    **3. Conditional queries.**
    It is easier to construct conditional queries based on the value of the enum attribute. This is useful in controller actions or services that requires multiple criteria when filtering records.

    ```
    tasks = Task.where(status: [:paused, :archived])
    ```


    State management
    **4. State management.**
    Enums are often used to manage state transitions. This is very useful for workflows or state machine scenarios where filters are required based on the record's state.

    ```
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }


    scope :not_archived, -> {where.not (status: archived }
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    scope :not_archived, -> {where.not (status: archived }
    end

    workable_tasks = Task.not_archived
    ```


    Integration with form helpers
    **5. Integration with form helpers.**
    Enums allows easy creation of select drop downs in forms This makes the values in forms are consistent with the defined enum values.


    ```
    <%= form_with model: @task do |f| %>
    <%= f.label :status %>
    <%= f.select :status, Task.statuses.keys.map { |s|=[s.humanize, s] } %>
    <%= f.submit %>
    <%= f.label :status %>
    <%= f.select :status, Task.statuses.keys.map { |s| [s.humanize, s] } %>
    <%= f.submit %>
    <% end %>

    ```

    ActiveRecord callbacks
    **6. ActiveRecord callbacks.**
    Enums can be combined with ActiveRecord callbacks to perform actions based on the state of the enum attribute.

    ```
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    after_update:notify_managers, if: status_changed?
    after_update:notify_managers, if: status_changed?
    def notify_managers
    # send notifications to managers about task changes
    end
    def notify_managers
    # send notifications to managers about task changes
    end
    end

    ```

    With these powerful implementations of enums, there are some limitations: First is the database support, enum support is built into ActiveRecord and doesn't rely on the database's enum types. Enum will work with any database supported by ActiveRecord. Another is the migration considerations, if there will be changes in the enum values, careful handling is necessary to avoid migration inconsistencies.

  8. jcuervo revised this gist Jun 21, 2024. 1 changed file with 8 additions and 3 deletions.
    11 changes: 8 additions & 3 deletions enums_for_scoping.md
    Original file line number Diff line number Diff line change
    @@ -1,15 +1,20 @@
    Provided in ActiveRecord, enums are used to define a set of named values for an attribute on a model. The basic implementation for enums are for attributes that relates to status, stages and states.
    ## Unveiling the Power of Enums for Scoping Queries in Rails

    Provided in [ActiveRecord](https://api.rubyonrails.org/classes/ActiveRecord/Enum.html), enums are used to define a set of named values for an attribute on a model. The basic implementation for enums are for attributes that relates to status, stages and states.

    ```
    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    end
    Enums provide symbolic names for values, making the code more readable and self-explanatory. For the code above, '0, 1, 2, 3 and 4' will be saved in the field status for the Task model and the respective table field in the database. Rather than the numbers, the symbolic names pending, active, completed, paused, and archived' will be referred to in the code.
    ```

    Enums provide symbolic names for values, making the code more readable and self-explanatory. For the code above, `0, 1, 2, 3 and 4` will be saved in the field status for the Task model and the respective table field in the database. Rather than the numbers, the symbolic names `pending, active, completed, paused, and archived` will be referred to in the code.

    Enums make sure that only the predefined values can be used for the specified attribute, thus reducing errors. The values are stored as integers in the database which is more efficient in storage than strings. Enums will also automatically generate helpful methods and scopes for querying.

    Let's walk though several powerful features of enums:

    Query methods.
    1. Query methods.
    The generated query methods for each value makes querying based on the enum's state very straightforward. With the code above, we can write the query methods like:

    pending_tasks = Task.pending
  9. jcuervo created this gist Jun 21, 2024.
    83 changes: 83 additions & 0 deletions enums_for_scoping.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,83 @@
    Provided in ActiveRecord, enums are used to define a set of named values for an attribute on a model. The basic implementation for enums are for attributes that relates to status, stages and states.

    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }
    end
    Enums provide symbolic names for values, making the code more readable and self-explanatory. For the code above, '0, 1, 2, 3 and 4' will be saved in the field status for the Task model and the respective table field in the database. Rather than the numbers, the symbolic names pending, active, completed, paused, and archived' will be referred to in the code.

    Enums make sure that only the predefined values can be used for the specified attribute, thus reducing errors. The values are stored as integers in the database which is more efficient in storage than strings. Enums will also automatically generate helpful methods and scopes for querying.

    Let's walk though several powerful features of enums:

    Query methods.
    The generated query methods for each value makes querying based on the enum's state very straightforward. With the code above, we can write the query methods like:

    pending_tasks = Task.pending
    active_tasks = Task.active
    completed_tasks = Task.completed
    paused_tasks = Task.paused


    Scopes for enums.
    We can build custom scopes for each enum values which in turn provides complex but readable queries.

    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4}


    scope :recent_pending, -> { pending. where ( 'created at > ?', Date.current) }
    end


    recent_pending_tasks = Task.recent_pending


    Conditional queries.
    It is easier to construct conditional queries based on the value of the enum attribute. This is useful in controller actions or services that requires multiple criteria when filtering records.

    tasks = Task.where(status: [:paused, :archived])


    State management
    Enums are often used to manage state transitions. This is very useful for workflows or state machine scenarios where filters are required based on the record's state.

    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }


    scope :not_archived, -> {where.not (status: archived }

    end


    workable_tasks = Task.not_archived


    Integration with form helpers
    Enums allows easy creation of select drop downs in forms This makes the values in forms are consistent with the defined enum values.


    <%= form_with model: @task do |f| %>
    <%= f.label :status %>
    <%= f.select :status, Task.statuses.keys.map { |s|=[s.humanize, s] } %>
    <%= f.submit %>
    <% end %>


    ActiveRecord callbacks
    Enums can be combined with ActiveRecord callbacks to perform actions based on the state of the enum attribute.

    class Task < ApplicationRecord
    enum status: { pending: 0, active: 1, completed: 2, paused: 3, archived: 4 }

    after_update:notify_managers, if: status_changed?

    def notify_managers
    # send notifications to managers about task changes
    end
    end


    With these powerful implementations of enums, there are some limitations: First is the database support, enum support is built into ActiveRecord and doesn't rely on the database's enum types. Enum will work with any database supported by ActiveRecord. Another is the migration considerations, if there will be changes in the enum values, careful handling is necessary to avoid migration inconsistencies.

    Enums in Ruby on Rails provides powerful and expressive means to handle attributes with predefined set of values either in scope queries, state management and thus improving code readability and maintainability. Leveraging this feature also ensures consistency across the application.