Reputation: 41
I am trying to make a booking system for restaurants in Ruby on Rails. I have three tables: users, tables and reservations. 'users' has the columns 'id', 'name', 'email', 'phone' and 'totalPersons'. 'table' has the columns 'id' and 'seats'. 'reservations' has the columns 'id', 'user_id', 'table_id' and 'begin_datetime'.
The models look like this:
class User < ActiveRecord::Base
has_many :reservations
has_many :tables, :through => :reservations
end
class Table < ActiveRecord::Base
has_many :reservations
has_many :users, :through => :reservations
end
class Reservation < ActiveRecord::Base
belongs_to :table
belongs_to :user
end
I was able to join the tables
and reservations
tables but I was unable to join the three together.
I am trying to show a full reservation with name and at what table the user is.
<table>
<thead>
<tr>
<th>Reserverings ID</th>
<th>Tafel nummer</th>
<th>Seats</th>
<th>User</th>
<th>Begint om</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<% @tables.each do |table| %>
<tr>
<td><%= reservation.id %></td>
<td><%= reservation.table_id %></td>
<td><%= table.seats %></td>
<td><%= user.name %></td>
<td><%= reservation.begin_datetime %></td>
<td><%= link_to 'Show', table %></td>
<td><%= link_to 'Edit', edit_table_path(table) %></td>
<td><%= link_to 'Destroy', table, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
In the controller my join looks like
@reservations = reservation.joins(:tables, :users)
Can you help me? Rails version 4.0
EDIT: On http://guides.rubyonrails.org/ I saw
Post.joins(:comments => :guest)
The SQL that is produced is:
SELECT posts.* FROM posts
INNER JOIN comments ON comments.post_id = posts.id
INNER JOIN guests ON guests.comment_id = comments.id
I guess my SQL code for the all reservations with users and the table they booked would look like
SELECT * FROM reservations, users, tables
INNER JOIN reservations ON reservations.user_id = users.id
INNER JOIN reservations ON reservations.table_id = tables.id
Maybe that will clarify things for you. So now I need to know how that is produced in ruby on rails.
Upvotes: 4
Views: 27883
Reputation: 2853
Rails allows You to write custom join conditions inside a string, like this:
Reservation.joins('INNER JOIN "tables" ON "tables"."id" = "reservations"."table_id" INNER JOIN "users" ON "users"."id" = "reservations"."user_id"')
or much cleaner just specify several join clauses:
Reservation.joins(:user).joins(:table)
To extract data you need just apply a few custom select
clauses, like this:
Reservation.joins(:user).joins(:table).select("tables.seats AS table_seats")
Same as with join, you can apply several of those. Each of the returned objects in collection will have a same name method as You defined the column name after "AS" (in this case it will be . There is a catch though - all these will be returned as strings because AR can't really guess what those are.
Upvotes: 7
Reputation: 5528
You should use "includes" instead of "joins". Also when you're looping through @tables to print the reservations, reservation and user aren't defined. You need to at least say:
@tables.each do |table|
reservation = table.reservation
user = reservation.user
...
end
Upvotes: 1