简体   繁体   中英

Creating polymorphic associations has_many/has_one

I have two rails models - Shipments and Notes. Notes is a polymorphic association with a body and status.

A shipment can have many notes. ( has_many :notes, as: :notable )

However, I'd also like to create a has_one relationship in Shipments to show the most recent note with a status that isn't null.

I've tried a few different things but with no luck, including the code below. Anyone know how I can do this? I'm using ruby on rails 4. Please let me know if I can provide any other information.

has_one :last_note_with_status, -> { where('notes.notable_type = Shipment') .where('notes.status is not null') .order(created_at: :desc) }, class_name: 'Note'

Maybe you don't need a has_one clause to achieve that. I think the best way to achieve it is to create a couple scopes on notes:

class Note
  scope :latest, order(created_at: :desc).limit(1)
  scope :with_status, where("status is not null")
end

and declare a method in your shipment class:

class Shipment
  def latest_note_with_status
    notes.latest.with_status.first
  end
end

You don't have the foreign key...

has_one :last_note_with_status, 
  -> { where(notable_type: 'Shipment').where.not(status: nil) }, 
  class_name: 'Note',
  foreign_key: :notable_id

This will give you a single record. From the sounds of what you are wanting, something like this might work:

  scope: :last_unresolved, joins(:notes)
     .where('notes.created_at = (SELECT MAX(notes.created_at) FROM notes WHERE notes.notable_id = shipments.id AND notes.notable_type = "Shipment")')
     .where('notes.status NOT IN (?)', ["Delivered", "Resolved"])
     .where('shipments.status NOT IN (?)', ["Delivered", "Resolved"])
     .group('shipments.id')

Untested, but you can try something like this

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM