Giter Club home page Giter Club logo

Comments (4)

tiagoengel avatar tiagoengel commented on May 30, 2024 1

My initial idea for supporting relationships was to mimic the ecto relationships.
This way it will be easy to maintain the support for ecto models.

The idea is to have the same functions ecto have to check the relationships.

__schema__(:associations) returns all association names.
__schema__(:association, name) returns the association reflection.

I actually implemented those functions (without the reflections), you can take a look here.

An association reflection in ecto looks like this:

# BelongsTo
%Ecto.Association.BelongsTo{cardinality: :one, defaults: [], field: :company,
   on_cast: nil, on_replace: :raise, owner: App.Activity,
   owner_key: :company_id, queryable: App.Company,
   related: App.Company, related_key: :id, relationship: :parent}

# HasOne
%Ecto.Association.Has{cardinality: :one, defaults: [], field: :department,
 on_cast: nil, on_delete: :nothing, on_replace: :raise,
 owner: App.Activity, owner_key: :id,
 queryable: App.Department, related: App.Department,
 related_key: :activity_id, relationship: :child}

# HasMany
%Ecto.Association.Has{cardinality: :many, defaults: [],
 field: :product_activities, on_cast: nil, on_delete: :nothing,
 on_replace: :raise, owner: App.Activity, owner_key: :id,
 queryable: App.ProductActivity, related: App.ProductActivity,
 related_key: :activity_id, relationship: :child}

We don't need to add all these fields only the ones dayron needs

Ecto also have the Ecto.Association.NotLoaded module to indicate an association
is not loaded.

Having all this information about the associations I think we can easily parse the relationships.
Maybe adding a method build in every Model that will first build the associations if they're present
and only after that call the struct method.

If we add support for all this I think adding the api to fetch associations will be straightforward.

from dayron.

tiagoengel avatar tiagoengel commented on May 30, 2024

So, I'm thinking in adding support for has_many, has_one and belongs_to.
Here's a draft of the api.

The Dayron.Model will now support the has_many, has_one and belongs_to keys.
The value of this keys would be keyword lists

defmodule MyApp.User do
  # api requests to http://api.example.com/users
  use Dayron.Model, resource: "users", has_many: comments: Comment

  # struct defining model attributes
  defstruct name: "", age: 0
end


defmodule MyApp.Comment do
  use Dayron.Model, resource: "comments", belongs_to: user: MyApp.User

  defstruct text: ""
end

Support for the ecto schema will still be the same

defmodule MyApp.User do
  use Ecto.Schema
  use Dayron.Model

  schema "users" do
    field :name, :string
    field :age, :integer, default: 0
    has_many :comments, MyApp.Comment
  end
end

defmodule MyApp.Comment do
  use Ecto.Schema
  use Dayron.Model

  schema "comments" do
    field :text, :string
    belongs_to: :user, MyApp.User
  end
end

And the api will be used like this:

RestRepo.all(post, :comments) # => get users/:id/comments
RestRepo.get(post, :comments, comment_id) #=> get users/:id/comments/:comment_id
RestRepo.update!(post, :comments, comment_id, comment_params) # => put users/:id/comments
RestRepo.insert!(post, :comments, comments_params) #=> post users/:id/comments
RestRepo.delete!(post, :comments, comment_id) #=> delete users/:id/comments/:id

For now I'm not planing to suport nested preloads like RestRepo.get(post, [:comments, :attachments], comment_id) but this can be added in the future.

Also, if the json response already have the relationships, it will be parsed normally.

GET users/1

{id: 1, name: "john doe", comments: {id: 1, text: "that's a comment"}}

The Post returned by this get will have the comment property already loaded.
In this case I'm thinking in adding the RestRepo.assoc_loaded?(post, :comments) so
the user can check this before sending another request.

What do you think?

from dayron.

tiagoengel avatar tiagoengel commented on May 30, 2024

Thinking a little bit better, I think #43 and #44 should be done before this because for this to work we will need to support data mapping for ecto relationships.

from dayron.

flaviogranero avatar flaviogranero commented on May 30, 2024

@tiagoengel I like your proposal, and also agree with other tasks dependencies. It's a good plan to check Ecto 2 changes before going with this.

from dayron.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.