belongs_to and has_many macros provide a rails like mapping between Objects.
classUser<Granite::ORM::Base adapter mysql has_many :posts field email :String field name :String timestampsend
This will add a posts instance method to the user which returns an array of posts.
classPost<Granite::ORM::Base adapter mysql belongs_to :user field title :String timestampsend
This will add a user and user= instance method to the post.
For example:
user = User.find1user.posts.eachdo|post|puts post.titleendpost = Post.find1puts post.userpost.user= userpost.save
In this example, you will need to add a user_id and index to your posts table:
CREATE TABLE posts ( id BIGSERIAL PRIMARY KEY, user_id BIGINT, title VARCHAR, created_at TIMESTAMP, updated_at TIMESTAMP);CREATE INDEX 'user_id_idx' ON TABLE posts (user_id);
Many to Many
Instead of using a hidden many-to-many table, Granite recommends always creating a model for your join tables. For example, let's say you have many users that belong to many rooms. We recommend adding a new model called participants to represent the many-to-many relationship.
Then you can use the belongs_to and has_many relationships going both ways.
classUser<Granite::ORM::Base has_many :participants field name :StringendclassParticipant<Granite::ORM::Base belongs_to :user belongs_to :roomendclassRoom<Granite::ORM::Base has_many :participants field name :Stringend
The Participant class represents the many-to-many relationship between the Users and Rooms.
Here is what the database table would look like:
CREATE TABLE participants ( id BIGSERIAL PRIMARY KEY, user_id BIGINT, room_id BIGINT, created_at TIMESTAMP, updated_at TIMESTAMP);CREATE INDEX 'user_id_idx' ON TABLE participants (user_id);CREATE INDEX 'room_id_idx' ON TABLE participants (room_id);
has_many through:
As a convenience, we provide a through: clause to simplify accessing the many-to-many relationship:
classUser<Granite::ORM::Base has_many :participants has_many :rooms,through: participants field name :StringendclassParticipant<Granite::ORM::Base belongs_to :user belongs_to :roomendclassRoom<Granite::ORM::Base has_many :participants has_many :users,through: participants field name :Stringend
This will allow you to find all the rooms that a user is in:
user = User.firstuser.rooms.eachdo|room|puts room.nameend