balvig/spyke

Suggestion: Make difference between has_many and embeds_many

Closed this issue · 5 comments

For example:

class Author < Spyke::Base
  ....
  has_many :books, uri: nil
  attributes :name, :age
end

class Book < Spyke::Base
  ....
  attributes :title, :part
end

When I try to add a book to the author

author.books.build(my_attributes)

Spyke adds an author_id to the embedded book, which is, in embedded documents unnecessary:

Author:

{
  "name": "J.R.R. Tolkien",
  "age": 102,
  "books": [
    {
      "title": "The Fellowship of the Ring",
      "part": "Part 1"
    }, {
      "title": "The Two Towers",
      "part": "Part 2"
    }, {
      "title": "The Return of the King",
      "part": "Part 3"
    }
  ]
}

As, per intention, all books belongs to this specific author, there's no need to add an author_id to the books within embedded models.

Or is it possible that I misunderstand your intentions with the has_many associations?

Greetings
Klaus

Hello there!

Hmmm yes...I think that somehow makes sense. I've made a PR that addresses it in #59 but haven't completely figured out if there is any draw back to this...only thing I can think of at the moment is if you set up a belongs_to on the embedded object and want to go:

author.book.author 
#=> book doesn't have `author_id` so is unable to build URL for `/authors/:id`

...but perhaps that's a bit of a strange example...Could you maybe try out the branch and see how it works for you?

Hey Jens,

sorry, I'm very busy with some server problems at the moment, but I will give it a try as soon as will have time for it.

Hey,
nice job, it works as intended.

I want to make another suggestion in this context:

What do you think about three methods?

has_one:, has_many: (always expecting an uri as parameter),
embeds: (mustn't have an uri as parameter), but embedded models are always stored as an array, independent whether they are just one or many.

So you have a clear difference between embedded models and related tables (such as joins in sql)

Ah I see, basically uri:nil fullfils this purpose for now and I haven't personally felt a need for an extra method! 😄

Sure, it would just be a bit cosmetic, but not necessary ;)