简体   繁体   中英

How do I create two relationships to the same model with different names?

I have two Rails 4 models: Journey and Place. I would like a Journey two have two fields, origin and destination, that are both Places. My Journey class looks like this:

class Journey < ActiveRecord::Base
  has_one :origin, class_name: :place
  has_one :destination, class_name: :place
end

Firstly, do I also need something in my Place class? I thought I would need two "has_many" declarations, but I couldn't work out the syntax given the two references.

Secondly, would it be possible to reference the origin Place of a Journey using syntax like "j.Origin", where "j" is a Journey record? (And similarly for the destination.)

In theory, these relations should work for you:

class Journey < ActiveRecord::Base
  belongs_to :origin,      class_name: :place
  belongs_to :destination, class_name: :place
end

class Place < ActiveRecord::Base
  has_many :origin_journeys,      foreign_key: origin_id,      class_name: :journey
  has_many :destination_journeys, foreign_key: destination_id, class_name: :journey

  def all_journeys
    Journey.where("origin_id = :place_id OR destination_id = :place_id", place_id: self.id)
  end
end

Usage:

# controller for exemple
def journeys_of_that_place
  @place = Place.find(params[:id])
  @journeys = @place.all_journeys
  @having_this_place_as_origin = @place.origin_journeys
end

# Question 2: Yes, it is possible
def update_origin
  @journey = Journey.find(params[:id])
  @journey.origin = Place.find(params[:place_id])
  @journey.save
end

To answer your questions:

  1. You don't need anything in your Place class unless you want to be able to access Journey records from a Place . However, you will need a foreign key journey_id on the places table.

    I'd consider setting up scopes on Place that would return Journey objects which started or ended in that place, if you think you might need them. Check out the docs on has_one and belongs_to .

  2. Yep. That's what the association is there for. This SO question may help shed some light on it as well.

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