Skip to content

Commit

Permalink
Version 0.4.3 - Add support for polymorphic belongs_to
Browse files Browse the repository at this point in the history
  • Loading branch information
brendon committed Nov 17, 2024
1 parent 7eb3ccd commit b6ac7ee
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## [Unreleased]

## [0.4.3] - 2024-11-18

- Add support for polymorphic `belongs_to` where we add both the `id` and the `type` to the scope.

## [0.4.2] - 2024-11-08

NOTE: Versions 0.4.0 and 0.4.1 contain fatal flaws with the locking logic. Upgrade as soon as you can.
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ You should also add an index to ensure that the `position` column value is uniqu

The above assumes that your items are scoped to a parent table called `lists`.

If you have a polymorphic `belongs_to` then you'll want to add the type column to the index also:

`add_index :items, [:listable_id, :listable_type, :position], unique: true`

The Positioning gem uses `0` and negative integers to rearrange the lists it manages so don't add database validations to restrict the usage of these. You are also restricted from using `0` and negative integers as position values. If you try, the position value will become `1`. If you try to set an explicit position value that is greater than the next available list position, it will be rounded down to that value.

### Declaring Positioning
Expand Down Expand Up @@ -66,6 +70,10 @@ positioned on: :type
belongs_to :list
belongs_to :category
positioned on: [:list, :category, :enabled]

# If your belongs_to is polymorphic positioning will automatically add the type to the scope
belongs_to :listable, polymorphic: true
positioned on: :listable
```

### Initialising a List
Expand Down
1 change: 1 addition & 0 deletions lib/positioning.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def positioned(on: [], column: :position)

if reflection&.belongs_to?
positioning_columns[column][:scope_columns] << reflection.foreign_key
positioning_columns[column][:scope_columns] << reflection.foreign_type if reflection.polymorphic?
positioning_columns[column][:scope_associations] << reflection.name
else
positioning_columns[column][:scope_columns] << scope_component
Expand Down
5 changes: 5 additions & 0 deletions test/models/entity.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Entity < ActiveRecord::Base
belongs_to :includable, polymorphic: true

positioned on: :includable
end
8 changes: 8 additions & 0 deletions test/support/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@
t.string :name
end

create_table :entities, force: true do |t|
t.string :name
t.integer :position, null: false
t.references :includable, polymorphic: true
end

add_index :entities, [:includable_id, :includable_type, :position], unique: true

create_table :items, force: true do |t|
t.string :name
t.integer :position, null: false
Expand Down
5 changes: 5 additions & 0 deletions test/test_positioning.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
require_relative "models/author/teacher"
require_relative "models/blog"
require_relative "models/post"
require_relative "models/entity"

class TestRelativePositionStruct < Minitest::Test
def test_struct_takes_keyword_arguments
Expand Down Expand Up @@ -614,6 +615,10 @@ def test_that_position_columns_will_cope_with_standard_columns
assert_equal({position: {scope_columns: ["list_id", "enabled"], scope_associations: [:list]}}, Author.positioning_columns)
end

def test_that_position_columns_will_cope_with_polymorphic_belong_to
assert_equal({position: {scope_columns: ["includable_id", "includable_type"], scope_associations: [:includable]}}, Entity.positioning_columns)
end

def test_that_position_columns_must_have_unique_keys
assert_raises(Positioning::Error) do
Item.send :positioned, on: :list
Expand Down

0 comments on commit b6ac7ee

Please sign in to comment.