'Creating link table to connect one to one relationship of same model
I want to make sure table join with joining table has strong one-to-one relationship. Following is example Run generator
bundle exec rails g model Page name:string content:text
bundle exec rails g model PageAssociation left_page_id:integer right_page_id:integer
After running these generator, I have to change my page model following
class Page < ApplicationRecord
has_one :left_page_association, :foreign_key => :left_page_id,
:class_name => 'PageAssociation'
has_one :right_page_association, :foreign_key => :right_page_id,
:class_name => 'PageAssociation'
has_one :left_page, :through => :left_page_association,
:source => :right_page
has_one :right_page, :through => :right_page_association,
:source => :left_page
end
In my association table model page_association
class PageAssociation < ApplicationRecord
belongs_to :left_page, class_name: 'Page'
belongs_to :right_page, class_name: 'Page'
end
Now using rails c I can do following
page_one = Page.create(name: 'first page', content: 'first page content')
page_two = Page.create(name: 'second page', content: 'second page content')
PageAssociation.create(left_page: page_one, right_page: page_two)
page_one.left_page
page_two.right_page
All working fine and it is returning pages. but I can do also this
page_three = Page.create(name: 'third page', content: 'third page content')
PageAssociation.create(left_page: page_one, right_page: page_three)
Of course it still shows on relationship due to has_one but it is creating another relationship. So I want following
- Only one association can be created and it should not allow another one
- What is best way to do this as we have million of records
- Is it one to use page.left_page? or is there any other optimised way to do same thing.
- Should I add indexing using following migration lines. Does it effect performance.
add_foreign_key :page_associations, :pages, column: :left_page_id
add_foreign_key :page_associations, :pages, column: :right_page_id
I changed migration to make column value unique, so it now give error when I create another PageAssociate with same page.id but is it right way?
t.integer :left_page_id, null: false, index: { unique: true }
t.integer :right_page_id, null: false, index: { unique: true }
what problem I am solving
So I have books table where I have multiple books, but some books borrow pages from one another. So suppose I have book-A and book-B so I want to show relationship of book-a to book-b. If they are related then I will create another relationship of book-a page-10 linked to book-b page 20, so when I click on book-a to synchronise, it will bring all changes of book-b page 20 in my book-a. So above is my first step to connected two books. I understand solving it using self join and keys is best but I can't do as we have huge number of records so that is not possible. So I have used above method to do it. But I did add unique constraints on db and validations in model to solve it. but I feel it is still not good way of doing it. later one I will make following
main-book , main-book-page, secondary-book-page
This will allow me to bound later pages each other. The name book and pages are fictions, actually entities are different.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
