Torrm
Torrm

Reputation: 153

Rails Model Associations when nesting - Confusion

Perhaps I am approaching this all wrong, I have the following models setup:

The User model has many Questions, a Question belongs_to a User

This means I can easily do: u = User.last.questions and see all of the questions associated with the user last added.

Following this, I have a Payment model that belongs_to a Question. A Question has_one payment meaning I can easily do u = User.last.questions.last.payment, getting the payment details from the question last added by the last added user (daft example perhaps!).

Now the bit that is confusing me

I have a model called PaymentOption which is used to populate a drop down list, for different prices, the PaymentOption belongs_to a Payment and a Payment has_one PaymentOption

This is all working correctly, but the only way for me to find out the details of the payment option, such as the amount, would be to do something like this:

payment_amount = PaymentOption.find(User.last.questions.last.payment.payment_option_id).amount

Ideally I would do something like this: amount = User.last.questions.last.payment.payment_option.amount

By doing it in the way I have, it is as good as doing two seperate queries, one to get the payment option ID and another to find a detail relating to that particular payment option. Surely there is a better way to approach this?

Thanks in advance

EDIT 1

To clarify my answer, I have included the schema for Payments and PaymentOptions

create_table "payment_options", force: :cascade do |t|
  t.integer  "amount"
  t.text     "description"
  t.string   "title"
  t.boolean  "user_accessible", default: true
  t.datetime "created_at",                     null: false
  t.datetime "updated_at",                     null: false
end

create_table "payments", force: :cascade do |t|
  t.string   "email"
  t.string   "token"
  t.integer  "question_id"
  t.datetime "created_at",        null: false
  t.datetime "updated_at",        null: false
  t.integer  "payment_option_id"
end

add_index "payments", ["payment_option_id"], name:    "index_payments_on_payment_option_id"
add_index "payments", ["question_id"], name: "index_payments_on_question_id"

Upvotes: 1

Views: 48

Answers (1)

lcguida
lcguida

Reputation: 3847

I think here is you problem:

I have a model called PaymentOption which is used to populate a drop down list, for different prices, the PaymentOption belongs_to a Payment and a Payment has_one PaymentOption

You said you've setup Payment has_one PaymentOption and PaymentOption belongs_to Payment. But in the schema described in the end Payment has a payment_option_id.

In this case, Payment belongs_to PaymenteOption and not the opposite. See this example in the Rails Guide. Account has supplier_id so Supplier has one Account and Account belongs_to Supplier.

Your models should be like this:

class Payment < ActiveRecord::Base

  belongs_to :payment_option

end

class PaymentOption < ActiveRecord::Base
  has_one :payment # Or even has_many :payments
end

Upvotes: 1

Related Questions