Reputation: 371
Use case: A user creates a service and can have many services. A user can book the service of another user through a servicebooking. A user can accept/decline the booking for their service from another user.
I am trying to display the outgoing service bookings made by the current user for another users services by checking a servicebookings model and also check/display the incoming bookings made by other users for the current users services on a myservicebookings page.
Myservicebookings view is as follows:
<h1>My Service bookings</h1>
<% if @owns_s %>
<table>
<tr>
<th><%= sortable "date" %></th>
<th><%= sortable "time" %></th>
<th><%= sortable "service name" %></th>
</tr>
<h4>Incoming requests:</h4>
<% @servicebookings.each do |servicebooking| %>
<tr>
<td><%= servicebooking.date %></td>
<td><%= servicebooking.time %></td>
<td><%= servicebooking.service_name %></td>
<td><%= link_to "View this booking", servicebooking_path(servicebooking) %></td>
</tr>
<% end %>
</table>
<%else%>
<%= "You have no incoming service booking requests"%>
<%end%>
<% if @owns_sb %>
<table>
<tr>
<th><%= sortable "date" %></th>
<th><%= sortable "time" %></th>
<th><%= sortable "service name" %></th>
</tr>
<h4>Outgoing requests:</h4>
<% @servicebookings.each do |servicebooking| %>
<tr>
<td><%= servicebooking.date %></td>
<td><%= servicebooking.time %></td>
<td><%= servicebooking.service_name %></td>
<td><%= link_to "View this booking", servicebooking_path(servicebooking) %></td>
</tr>
<% end %>
</table>
<%else%>
<%= "You have made no outgoing service booking requests"%>
<%end%>
<%= will_paginate @servicebookings %>
<%= link_to "Homepage", :controller => "welcome", :action => "index" %>
In my servicebookings controller I have the following to check whether a user owns a service or a servicebooking, currently it just returns all the services and servicebookings instead of displaying only the services created by the current user that another user has booking(incoming requests) and instead of displaying the services booked by the current user(outgoing requests). Can anyone give some tips here?? Thanks in advance guys, much appreciated.
def myservicebookings
@servicebookings = current_user.servicebookings.includes(:user).search(params[:search]).order(sort_column + " " + sort_direction).paginate(:per_page => 4, :page => params[:page])
owns_servicebooking = current_user.servicebookings.detect do |sb|
sb.user == current_user
end
owns_service = current_user.services.detect do |s|
s.user == current_user
end
@owns_sb = owns_servicebooking
@owns_s = owns_service
end
Servicebooking model:
class Servicebooking < ActiveRecord::Base
attr_accessible :service_id, :date, :time, :user_id, :service_name, :accept_booking
belongs_to :user
belongs_to :service
def self.search(search)
if search
where('name LIKE ?', "%#{search}%")
else
scoped
end
end
end
Services model:
class Service < ActiveRecord::Base
attr_accessible :avatar, :avatar2, :avatar3, :avatar4, :name, :date_available, :time_available, :description, :price, :size, :company_name, :company_details
has_attached_file :avatar, :default_url => "/images/:style/missing.png"
has_attached_file :avatar2, :default_url => "/images/:style/missing.png"
has_attached_file :avatar3, :default_url => "/images/:style/missing.png"
has_attached_file :avatar4, :default_url => "/images/:style/missing.png"
belongs_to :user
belongs_to :event
has_many :comments, dependent: :destroy
has_many :servicebookings
def self.search(search)
if search
where('name LIKE ?', "%#{search}%")
else
scoped
end
end
end
Upvotes: 1
Views: 203
Reputation: 76774
has_many :through
I think you'll benefit from the has_many :through
association
Your ServiceBooking
model seems to be a join model, which needs to reference booking_id
and service_id
The way you've got the system set up currently is to pull directly from this model. I think you'll be better to use it in conjunction with your other models. You'll literally just have to adapt your code slightly to affect this change:
#app/models/Service.rb
Class Service < ActiveRecord::Base
belongs_to :user
has_many :service_bookings
has_many :bookings, :through => :service_bookings
end
#app/models/Booking.rb
Class Booking < ActiveRecord::Base
belongs_to :user
has_many :service_bookings
has_many :services, :through => :service_bookings
end
#app/models/ServiceBooking.rb
Class Service < ActiveRecord::Base
belongs_to :service
belongs_to :booking
end
This will allow you to pull the actual data from the relative models, rather than just relying on the ServiceBooking
model
The beauty of this is that because you can add extra attributes to join models in Rails, you'll be able to include other fields, such as user_id
, inbound
and outbound
Your Code
I'd do it like this:
#config/routes.rb
resources :users do
resources :bookings
resources :services
end
#app/controllers/users_controller.rb
def index
user = User.find(params[:id])
@bookings = user.bookings
@services = user.services
end
#app/controllers/bookings_controller.rb
def index
user = User.find(params[:user_id])
@bookings = user.bookings
end
#app/controllers/services_controller.rb
def index
user = User.find(params[:user_id])
@services = user.services
end
This will allow you to display the actual bookings / services for each user (all the services / bookings on the user index
page; all relative records on bookings
and services
index actions)
Validation
If you follow these ideas, validation becomes somewhat more methodical
You can either use a before_create
function on your ServiceBooking
model (to check if the object matches the user_id), or you could perform some controller-based validation to see if the user_id
is consistent
I should also mention that checking ownership of booking
or service
moves to the other models with this (I.E service
belongs_to :user
)
Upvotes: 1