0

I have four tables in my db Movie, Showing, Ticket and Purchase. A Movie has many Showings, a Showing has many Tickets and a Purchase has many Tickets.

I'd like to constrain it so that all the Tickets in the Purchase can only be for exactly one Movie. I'm new to Rails and wondered if there was a way to do this in the Model. (validate or something similar)

2 Answers 2

1
class Purchase
  validate :validate_same_movie

  private

  def validate_same_movie
    movie_ids = tickets.map do |ticket|
      ticket.showing.movie.id
    end.uniq

    errors[:base] << "Can't have more than one movie in a purchase." if movie_ids.length > 1
  end
end

Something along these lines.

But I would also urge you to think about exactly why you're introducing this additional complexity into your system. In my experience, I typically buy movie tickets for the same movie at once and I don't recall when I've bought tickets for different movies in a single purchase. But just because I haven't done it doesn't mean nobody does. You're adding complexity and you're reducing functionality of your site. I'm not saying you don't have a valid reason, because I don't know what your app is.. but just a suggestion that you might think about if you really need this.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. It's not really movies and tickets, but the domain-specific terminology would detract.
Oh, well in that case ignore my second paragraph. :) Hope the validate code helps you out.
0

What about something like this?

class Purchase < ActiveRecord::Base
  has_one :movie
  has_many :tickets
end

class Ticket < ActiveRecord::Base
  has_one :purchase
end

class Movie < ActiveRecord::Base
  has_many :purchases
end

1 Comment

I don't wish to change the design to add a relationship between Movie and Purchase, I just want to constrain that Purchase must include Tickets for only one Movie.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.