Skip to content

Commit

Permalink
#235 - Ensure reverse query set creations are scoped to the related r…
Browse files Browse the repository at this point in the history
…ecord
  • Loading branch information
ellmetha committed Jun 8, 2024
1 parent a2a75a8 commit bfe94e6
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 4 deletions.
4 changes: 4 additions & 0 deletions docs/docs/models-and-databases/relationships.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ article_3 = Article.create!(title: "Third article", author: author_1)
# List the first author's articles
author_1.articles.to_a # [#<Article:0x1036e3ee0 id: 1, title: "First article", author_id: 1>,
# #<Article:0x1036e3e70 id: 3, title: "Third article", author_id: 1>]
# Create an article associated with the first author
article_4 = author_1.articles.create!(title: "Fourth article")
article_4.author # => #<Author:0x101590c40 id: 1, full_name: "Foo Bar">
```

:::tip
Expand Down
56 changes: 56 additions & 0 deletions spec/marten/db/query/related_set_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,60 @@ describe Marten::DB::Query::RelatedSet do
qset.all.to_set.should eq(Set{post_1, post_3})
end
end

describe "#create" do
it "creates a new record with the related field set" do
user = TestUser.create!(username: "jd1", email: "[email protected]", first_name: "John", last_name: "Doe")

qset = Marten::DB::Query::RelatedSet(Post).new(user, "author_id")

new_post = qset.create(title: "Post")

new_post.valid?.should be_true
new_post.persisted?.should be_true
new_post.author.should eq user
end

it "creates a new record with the related field set when a block is used" do
user = TestUser.create!(username: "jd1", email: "[email protected]", first_name: "John", last_name: "Doe")

qset = Marten::DB::Query::RelatedSet(Post).new(user, "author_id")

new_post = qset.create do |p|
p.title = "Post"
end

new_post.valid?.should be_true
new_post.persisted?.should be_true
new_post.author.should eq user
end
end

describe "#create!" do
it "creates a new record with the related field set" do
user = TestUser.create!(username: "jd1", email: "[email protected]", first_name: "John", last_name: "Doe")

qset = Marten::DB::Query::RelatedSet(Post).new(user, "author_id")

new_post = qset.create!(title: "Post")

new_post.valid?.should be_true
new_post.persisted?.should be_true
new_post.author.should eq user
end

it "creates a new record with the related field set when a block is used" do
user = TestUser.create!(username: "jd1", email: "[email protected]", first_name: "John", last_name: "Doe")

qset = Marten::DB::Query::RelatedSet(Post).new(user, "author_id")

new_post = qset.create! do |p|
p.title = "Post"
end

new_post.valid?.should be_true
new_post.persisted?.should be_true
new_post.author.should eq user
end
end
end
6 changes: 6 additions & 0 deletions src/marten/db/query/related_set.cr
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ module Marten
end
end

protected def build_record(**kwargs)
record = M.new(**kwargs)
record.assign_related_object(@instance, @related_field_id)
record
end

protected def clone(other_query = nil)
RelatedSet(M).new(
instance: @instance,
Expand Down
12 changes: 8 additions & 4 deletions src/marten/db/query/set.cr
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ module Marten
# query_set.create(title: "My blog post")
# ```
def create(**kwargs)
object = M.new(**kwargs)
object = build_record(**kwargs)
object.save(using: @query.using)
object
end
Expand All @@ -266,7 +266,7 @@ module Marten
# end
# ```
def create(**kwargs, &)
object = M.new(**kwargs)
object = build_record(**kwargs)
yield object
object.save(using: @query.using)
object
Expand All @@ -283,7 +283,7 @@ module Marten
# query_set.create!(title: "My blog post")
# ```
def create!(**kwargs)
object = M.new(**kwargs)
object = build_record(**kwargs)
object.save!(using: @query.using)
object
end
Expand All @@ -301,7 +301,7 @@ module Marten
# end
# ```
def create!(**kwargs, &)
object = M.new(**kwargs)
object = build_record(**kwargs)
yield object
object.save!(using: @query.using)
object
Expand Down Expand Up @@ -1179,6 +1179,10 @@ module Marten
{% end %}
end

protected def build_record(**kwargs)
M.new(**kwargs)
end

protected def clone(other_query = nil)
Set(M).new(
query: other_query.nil? ? @query.clone : other_query.not_nil!,
Expand Down

0 comments on commit bfe94e6

Please sign in to comment.