abhijit
abhijit

Reputation: 6703

Accessing Joint Table

If I have two table with a many_to_many relationship:

DB.create_table? :students do
  primary_key    :id
  String         :name
end

DB.create_table? :books do
  primary_key    :id
  String         :title
end

DB.create_table? :students_books do
  Integer        :num_days_borrowed

  foreign_key    :student_id,
                 :students,
                 :key => :id,
                 :allow_null => false

  foreign_key    :book_id,
                 :books,
                 :key => :id,
                 :allow_null => false
end

I have the following Sequel Classes:

class Student < Sequel::Model(:students)
  many_to_many  :books,
                :left_key => :student_id,
                :right_key => :book_id,
                :join_table => :students_books

  def borrowed(bk)
    add_book(bk)
  end
end

class Book < Sequel::Model(:books)
  many_to_many  :books,
                :left_key  => :book_id,
                :right_key  => :student_id,
                :join_table  => :students_books
end

So, now I can add books to students like this:

s1 = Student.create(:name => 'Hari')
b1 = Book.create(:title => 'Foundation')

s1.borrowed(b1)

My question is how do I assign values and retrieve the num_days_borrowed attribute using Sequel Model?

Upvotes: 1

Views: 197

Answers (2)

Jeremy Evans
Jeremy Evans

Reputation: 12139

Using a one_to_many with a join model is one way to do it (as Threeve mentioned), but you can also do so with your existing many_to_many books association by adding a :select=>[:books.*, :students_books__num_days_borrowed] option. Then on the returned books instances, use book[:num_days_borrowed] to get the value

Upvotes: 1

alkalinecoffee
alkalinecoffee

Reputation: 1013

You'll need to give Sequel some more information about your models.

In your Student and Book models, add one_to_many relationships between those models and the junction table (referencing the foreign key in the junction table).

Then create a StudentsBook model where you will set up many_to_one relationships between your junction table and the other tables.

But first, set the primary keys in your junction table:

DB.create_table :students_books do
  # add columns, etc
  primary_key [:student_id, :book_id]
end

Then set your models to look like this:

class Student < Sequel::Model(:students)
  many_to_many  :books,
                :left_key => :student_id,
                :right_key => :book_id,
                :join_table => :students_books
  one_to_many   :students_books, :key=>:student_id

  def borrowed(bk)
    add_book(bk)
  end
end

class Book < Sequel::Model(:books)
  many_to_many  :books,
                :left_key  => :book_id,
                :right_key  => :student_id,
                :join_table  => :students_books
  one_to_many   :students_books, :key=>:student_id
end

class StudentsBook < Sequel::Model(:students_books)
  many_to_one :book
  many_to_one :student
end

Now you can access any columns found in your junction table:

s1 = Student.create(:name => 'Hari')
b1 = Book.create(:title => 'Foundation')

s1.add_book(b1)
s1.students_books.first[:num_days_borrowed] = 10
s1.students_books.first.save

puts StudentsBook.first.inspect
  #=> #<StudentsBook @values={:num_days_borrowed=>10, :student_id=>1, :book_id=>1}>

Also pay attention to the pluralization of the junction table and the model name. It can be a bit tricky at first when it comes to junction tables.

Upvotes: 1

Related Questions