Ruby on Rails - has_one relation, how to check if it has an existing association?
Asked Answered
S

4

9

I have a simple problem, related to associations. I have a model for book, that has_one reservation. Reservation belongs_to book.

I want to make sure in the create method of reservations controller that a book is not reserved already when a reservation is made. In other words, I need to check if any other reservation exists for that book. How do i do that?

EDIT: Aaaand i made it, thanks everyone for the tips, learned some new stuff. When i tried offered solutions, I got no_method errors, or nil_class etc. That got me thinking, that the objects I'm trying to work on simply don't exist. Krule gave me the idea to use book.find, so i tried working with that. Ultimately i got it working with:

book=Book.find_by_id(reservation_params[:book_id])
unless book.is_reserved?

Thanks everybody for your anwsers, I know it's basic stuff but i learned a lot. Cheers!

Smart answered 30/12, 2013 at 22:32 Comment(2)
Hey, i tried book.reservation.any? and similar constructs. I think the problem is, object Book is not present in the reservations controller. The book id is passed as a parameter from a different controller.Smart
Better edit the question to add that data.Crayfish
E
4
#app/models/book.rb

def is_reserved?
  !self.reservation.nil?
end

# Somewhere else
book = Book.find(id)
book.is_reserved?
Etiolate answered 30/12, 2013 at 22:44 Comment(2)
Now getting error: undefined local variable or method `id' for #<ReservationsController:0x000000050ef3f8> I think the books are not visible in the reservations controller. The book id is passed from different controller as a parameter.Smart
You should use an actual book id variable instead of just writing id without instantiating it as variable. Something along the lines of id = params[:id] in controller or numeric value representing it should do the trick.Etiolate
I
9

How about:

self.reservation.present?

This should return true if an association exists.

Indian answered 29/3, 2016 at 5:30 Comment(1)
This has the unnecessary side effect of fetching the entire Reservation record from the database and instantiating it as an ActiveRecord instance, which is not necessary in order to find out if it exists.Cur
T
8

Little bit performance gain can be obtained if you use

#app/models/book.rb
def is_reserved?
  Reservation.exists?(book_id: id)
end

#somewhere else
book = Book.find(id)
book.is_reserved?
Torn answered 13/4, 2020 at 14:19 Comment(0)
E
4
#app/models/book.rb

def is_reserved?
  !self.reservation.nil?
end

# Somewhere else
book = Book.find(id)
book.is_reserved?
Etiolate answered 30/12, 2013 at 22:44 Comment(2)
Now getting error: undefined local variable or method `id' for #<ReservationsController:0x000000050ef3f8> I think the books are not visible in the reservations controller. The book id is passed from different controller as a parameter.Smart
You should use an actual book id variable instead of just writing id without instantiating it as variable. Something along the lines of id = params[:id] in controller or numeric value representing it should do the trick.Etiolate
H
1

Simply, use:

# book = Book.first
book.reservation.nil?   # returns true if no reservation
                        # is associated with this book
Hereunto answered 30/12, 2013 at 22:36 Comment(1)
It give me error: undefined local variable or method `book' for #<ReservationsController:0x0000000546a258>Smart

© 2022 - 2024 — McMap. All rights reserved.