Skip to content

Commit

Permalink
Support composite IDs
Browse files Browse the repository at this point in the history
Rails 7 supports composite primary keys, which means we need to pull the ID param with `extract_value`.
  • Loading branch information
codezomb committed Apr 21, 2024
1 parent af8947b commit daa64bd
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 2 deletions.
10 changes: 9 additions & 1 deletion lib/implicit_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def collection

def resource
@resource ||= if params[:id].present?
collection.find(params[:id])
collection.find(primary_key)
else
collection.new
end
Expand Down Expand Up @@ -64,4 +64,12 @@ def act_on_resource
end
end
end

def primary_key
if model_klass.primary_key.is_a?(Array)
params.try(:extract_value, :id)
else
params[:id]
end
end
end
13 changes: 13 additions & 0 deletions test/controllers/posts_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require "test_helper"
require "json"

class PostssControllerTest < ActionDispatch::IntegrationTest
test "show action returns the correct post" do
get post_url(posts(:composite_key)), headers: { "Accept" => "application/json" }
json_response = JSON.parse(@response.body)

assert_equal posts(:composite_key).author_id, json_response["author_id"]
assert_equal posts(:composite_key).slug, json_response["slug"]
assert_response :success
end
end
9 changes: 9 additions & 0 deletions test/dummy/app/controllers/posts_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class PostsController < ApplicationController
include ImplicitResource

private

def permitted_attributes(_resource)
params.require(:post).permit(:author_id, :slug)
end
end
2 changes: 2 additions & 0 deletions test/dummy/app/models/post.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class Post < ApplicationRecord
end
1 change: 1 addition & 0 deletions test/dummy/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
# root "posts#index"

resources :articles
resources :posts
end
10 changes: 10 additions & 0 deletions test/dummy/db/migrate/20240421044857_create_posts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class CreatePosts < ActiveRecord::Migration[7.1]
def change
create_table :posts, primary_key: [:author_id, :slug] do |t|
t.integer :author_id
t.string :slug,

t.timestamps
end
end
end
10 changes: 9 additions & 1 deletion test/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,20 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.1].define(version: 2024_03_29_195908) do
ActiveRecord::Schema[7.1].define(version: 2024_04_21_044857) do
create_table "articles", force: :cascade do |t|
t.string "title", null: false
t.text "body", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

create_table "posts", primary_key: ["author_id", "slug"], force: :cascade do |t|
t.integer "author_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "slug"
t.string "#<ActiveRecord::ConnectionAdapters::SQLite3::TableDefinition:0x0000ffff9de4e240>"
end

end
3 changes: 3 additions & 0 deletions test/fixtures/posts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
composite_key:
author_id: 1
slug: my-post-title

0 comments on commit daa64bd

Please sign in to comment.