Rails Multiple HABTM - ruby-on-rails

I'm building a rails application for an art exhibition website. At the moment I have 4 models, Curator, Exhibition, Artist, and Artwork.
The application should work as follow, An Exhibition can be curated by many curators, an exhibition can display multiple artworks, an artwork can be displayed in many exhibitions, artist can own many artworks, and artworks belongs to one artist.
I'm a rail newb and I'm having difficulty building the relationship between the models. Can you tell me if I'm doing this right, or maybe there is a better way?
curator.rb
class Curator < ActiveRecord::Base
has_and_belongs_to_many :exhibitions
end
exhibition.rb
class Exhibition < ActiveRecord::Base
has_and_belongs_to_many :curators
has_and_belongs_to_many :artworks
end
artwork.rb
class Artwork < ActiveRecord::Base
has_and_belongs_to_many :exhibitions
belongs_to :artist
end
artist.rb
class Artist < ActiveRecord::Base
has_many :artworks
end
Thanks!

I would recommend using has_many :through if you want to have validations on your relationships, use callbacks or want to add extra attributes.
If you want to have more information regarding this matter, this rails guide is great:
http://guides.rubyonrails.org/association_basics.html#choosing-between-has_many-through-and-has_and_belongs_to_many
Your HABTM looks fine though. If you run into any problem, it would be advisable to also reference your joined tables.

It looks right to me.. Do create the join tables naming convention would be:
curators_exhibitions
artworks_exhibitions
Hope you get the idea.
Also you would want to check out has_many :through in case you would want to do validations on top of the relationships!

Related

How to seed a new joining table in a Rails API db

I have two classes in my Rails API database, that I have just created a joining table for. I had seeded both classes previously so they have data. Now I would like to seed the joining class with id's from the existing data.
This is what the models look like for the first two classes:
class Stakeholder < ApplicationRecord
has_many :project_stakeholders
has_many :projects, through: :project_stakeholders
end
class Project < ApplicationRecord
has_many :project_stakeholders
has_many :stakeholders, through: :project_stakeholders
end
This is the model for my joining class:
class ProjectStakeholder < ApplicationRecord
belongs_to :project
belongs_to :stakeholder
end
Now I have two questions:
How to populate the joint class with data from the two first classes (project_id and stakeholder_id).
How can I check in the Rails console for values in the ProjectStakeholder class?
I have researched and tried different options from Stackoverflow but they don't seem to work. Rails guides do not provide an answer either, from what I have seen. Would be very grateful for some ideas!
You can just assign stakeholders to the project after creation
Project.first.stakeholders << Stakeholder.limit(5)
Project.second.stakeholders << Stakeholder.limit(5).offset(5)
You can check it in console in different ways:
Project.first.stakeholders.pluck(:id)
ProjectStakeholder.first

track history of active record changes and its association

I want to track the history the active record and association. I have a many to many
association:
class BookList
has_many :book_list_items
has_many :books, through: :book_list_items
end
class BookListItem
belongs_to :book
belongs_to :book_list
attr_accessable :position
end
class Book
has_many :book_list_items
has_many :book_lists, through: :book_list_items
end
how do I track the history of BookList like this:
add book to a book list
remove book from a book list
update position of a book in a book list
how do I implement this structure
http://railscasts.com/episodes/255-undo-with-paper-trail
This is a great rails cast that will work great for you based on the information you provided
You can also try active_snapshot. It is a much simpler and easy to use gem for model and its associations tracking for ruby and rails applications
I understand the question is too old for this answer, but this might help someone else

Rails 2 tables, 1 model

I am relatively new to ruby/rails and I have the following question:
I am working on a scheduling app and have a model named Classes and another named ClassEntries. The relationship between them is that each user can have multiple class entries per semester, each relating to one class. Each record in the Classes table belongs to a specific University. A User can have multiple entries in the ClassEntries table for 1 semester (typically 5). Their schedule is comprised of all their ClassEntries with the same semester ID.
I am not sure whether I should have a third model called Schedule that brings together the info in the ClassEntries and Classes models for the user at hand. I originally wrote this functionality in PHP and I simply used a MySQL JOIN to gather the necessary information. In Rails it seems that there should be a better way to accomplish this.
What would be the best way of going about this in Rails?
Many thanks
So, what you are looking for is pretty much associations in Rails.
You would have the following:
def User < ActiveRecord::Base
has_many :course_entries
has_many :courses, :through => :class_entries
end
def CourseEntry < ActiveRecord::Base
belongs_to :user
belongs_to :course
end
def Course < ActiveRecord::Base
has_many :course_entries
has_many :users, :through => :class_entries
end
With those associations set up, Rails would allow you to do such things like
some_user.courses or some_course.users and it will make the joins through CourseEntry for you.
Let me know if this helps. If you need me to go more in depth let me know.

What is the relationship between these two tables in RoR?

I am developing an application like the stackoverflow, which questions or articles have at less one tag. And one tags must have one or more articles.
So, I am doing this in migration in RoR. I am consider which relationship is suitable for both table. In article table, should use a "has_many", and in the tag table, should use "has_many".
But I am thinking is it necessary to add one more table in the middle, something like....
So, the first one is like that:
class Article < ActiveRecord::Base
has_many :tags
end
class Tag < ActiveRecord::Base
has_many :articles
end
or something like this:
class Article < ActiveRecord::Base
has_many :articleTagList
has_many :tags, :through => : articleTagLists
end
class Tag < ActiveRecord::Base
has_many :articleTagList
has_many :articles, :through => :articleTagLists
end
class ArticleTagList < ActiveRecord::Base
belongs_to :article
belongs_to :tag
end
Many-to-Many relationships in a normalized database will always need a third "look-up table."
If you denormalize you can get away with just having the tag id's in one field with a delimiter between them. But you also have to provide the logic to handle retrieval.
I'd personally just go with the normalized option.
If you don't want to store any information on the middle table (for example the name of the user who added tag X to the question Y), you can use the has_and_belongs_to_many:
http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_and_belongs_to_many
If you want to store something, you need to create the middle model, as your example. In your example, the ArticleTagList model should be called ArticlesTag and the database table should be articles_tags, by convention.

Ruby On Rails Relationships - One to Many

I'm a beginning to ROR, but here's what I'm trying to achieve. I have two items I want to associate: matters and people. Each matter can have many people. That is, I want to create people and matters separately and later be able to link them.
For example, I may create:
Bill Clinton
Barack Obama
I may create the matters:
Global warming
War on terror
I want to be able to associate the users Bill Clinton AND Barack Obama to BOTH matters. Can someone point me to a tutorial that can show me how to do this?
I think has_and_belongs_to_many is used less and less by the RoR community now. While still supported, I think it is now more common to have an intermediate model (in your case something like PoliticianMatter) to join your Politician and Matter models.
Then your politician_matter table will have a PK, a politician_id and a matter_id.
Then you have
class PoliticanMatter < ActiveRecord::Base
belongs_to :politician
belongs_to :matter
end
The advantage of this approach is that if there ever need to be future properties of the politician -> matter relationship (e.g importance, date of last occurrence) you have a model which affords this - has_and_belongs_to_many would not support the addition of these extra properties.
You can also access the many to many relationship directly from the Politician and Matter models like this
class Politician < ActiveRecord::Base
has_many :politician_matters
has_many :matters, :through => :politician_matters
end
class Matter < ActiveRecord::Base
has_many :politician_matters
has_many :politicians, :through => :politician_matters
end
You need a many2many relationship between these two entities.
A matter can be studied by many people
A person can studie several matters
Rails uses the has_and_belongs_to_many helper to do that. You'll find more about that in the documentation and many many blog posts!
has_and_belongs_to_many helper
class Politician < ActiveRecord::Base
has_and_belongs_to_many :tasks
end
class Task < ActiveRecord::Base
has_and_belongs_to_many :politicians
end
What you need are 3 tables:
politicians, tasks and politicians_tasks (having the two columns politician_id and task_id, no primary key)
Hope this helps
Seb

Resources