Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduces Hanami::Relation #579

Draft
wants to merge 47 commits into
base: main
Choose a base branch
from
Draft

Introduces Hanami::Relation #579

wants to merge 47 commits into from

Conversation

mereghost
Copy link
Member

@mereghost mereghost commented Apr 27, 2020

⚠️ Achtung: This is a true draft PR. The code is messy. The commit history is changing all the time and broken tests are a thing. ⚠️

This PR is the first step towards bringing model closer to rom.

In this we introduce the Relation abstraction in the same terms as rom does. This simplifies our code, boot process and exposes more of ROM to the users.


Most important changes

Modules instead of suffixes

Repositories, Entities and Relations are expected to be under a certain directory structure that should reflect a module structure. This follows the same rules for ROM auto-registration feature

Bookshelf::Relations::Books   #=> should exist under bookshelf/relations/books.rb
  • Relations
  • Entities
  • Repositories

Hanami::Relation

This PR introduces Hanami::Relation which maps directly to a ROM::Relation and offers the exact same API (being only an alias to it).

class ProjectName::Relations::Users < Hanami::Relation[:sql]
  schema(infer: true) do
    associations do
      has_many :books
    end
  end
end

Hanami::Repository

Hanami::Repository now takes the name of its root relation. Overall functionality is the same.

# This is moving to module namespacing soon
class BookRepository < Hanami::Repository[:books]
end

Hanami::Entity

Entity becomes a ROM::Struct

TODO

  • Update YARD docs
  • Remove unnecessary tests due to the new approach
  • Find a way to silence Repository method override (create, delete, update) (or remove if not needed)
  • Setup an easy way to instantiate an Entity (ROM)
  • Workout why some queries return ROM::Struct and others Hanami::Entity forcing both Relation and Repository to have the struct_namespace macro on them
  • Work out some unexpected behaviour:
class Books < ROM::Relation[:sql]
  schema(infer: true) do
    associations { belongs_to :author }
  end
end

class Authors < ROM::Relation[:sql]
  schema(infer: true) do
    associations { has_many :books }
  end
end

class Comments < ROM::Relation[:sql]
  schema(infer: true) do
   associations { belongs_to :user, as: :author }
  end
end

class Users < ROM::Relation[:sql]
  schema(infer: true) do
    associations { has_many :comments }
  end
end

class Repositories::Comment < ROM::Repository[:comments]
  def with_author
    root.combine(:author).to_a
  end
end

Repositories::Comment.new.with_author.first.author
#=> <ROM::Struct::Author id=50 name="Bob from the Upside Down" email=nil age=19 comments_count=0 active=true created_at=2020-07-17 14:20:24 UTC updated_at=2020-07-17 14:20:24 UTC>

In the case above, the returned struct is in fact a User, but ROM renamed it Author as the association is aliased (and this is kinda neat). Why this can become an issue? In the above example the project has an Author entity and relation, so this can get a little confusing.

@mereghost mereghost added this to the v2.0.0 milestone Apr 27, 2020
@mereghost mereghost self-assigned this Apr 27, 2020
@jodosha jodosha changed the base branch from unstable to main June 15, 2021 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants