First, some background.
My application models are like so:
User has_many :subscriptions; has_many :courses, :through => :subscriptions
Subscription belongs_to :course, :user
Course has_many :subscriptions; has_many :users, :through => :subscriptions
Subscription is a join table used to store information such as state (:active, :inactive, :failed, :passed, :unpaid) as well as serve as a connector to all the information that comes with taking a course (such as the Grade model(not yet added), the Payment model(work in progress), etc).
I want to add the Payment model to store a history of payments on a subscription. Each payment can be for one or more subscriptions. So far, I’ve tried a Payment has_many :subscriptions, but I’m having trouble with the controller logic and I’m thinking maybe there’s a better way to associate the models for “a Payment from a User on a Subscription to a Course.”
Technically speaking, in a payment show action, I would need information from each of these models (course.name, user_id of user who paid, payment.amount, all of which are connected to a Subscription) and in a Payment.create action, I’d need to set the state of the subscription (that I can do).
If this is a logical/efficient way to associate the various models, how do I access the needed information(some information from each model course, user, payment, and subscription) in the Payment show action with minimal database calls? I’m using Rails 3.2/Ruby 1.9 and would like to stick with ActiveRecord/ARel instead of straight sql statements. I’m open to “you’re doing it wrong” answers as well. If changing the associations will make it more efficient to access the tables from the controller, I’m open to that as well.
@D3mon-1stVFW’s answer set me on the right track to figure this problem out.
For the Payment show action, the queries would go something like:
This will make it possible to access the course and user data associated with a subscription like so:
For a payment new/create action where there is not yet a
payment.id, the queries are slightly different:Where
current_useris the user that is going to pay(create a new payment) and.unpaidis a scope on theSubscriptionmodel that looks like this:And in the view, you can access the data in the same way as with the show view:
My main point of confusion had been that I didn’t know you could access parent associations from the child. Subscription belongs_to Courses, yet you can still do
subscription.course.something.