How I would describe it should work:
A User Alice can initiate an Exchange with another User Bob. So Alice is the initiating user of this Exchange, and Bob is the requested user.
A User can have many Exchanges.
An Exchange has one initiating_user and one requested_user.
I am unsure if this is a 1-to-1 or 1-to-many relationship, since both are of User, but are not addressed with the same name.
An Exchange has exactly two Ratings, but the same problem as before applies. I do not know if this is a 1-to-1 or 1-to-many relationship.
Each one of initiating_user and requested_user can make a Rating.
Which is then the initiating_user_rating or requested_user_rating respectively.
A Rating belongs to exactly one Exchange.
My Problem:
I am almost certain that there is a much simpler approach than what I am using now, probably just with use of ActiveRecord relations.
It works at the moment, but I am not happy with it.
So I guess my questions are:
- Are those
initiating_user/requested_userandinitiating_user_rating/requested_user_ratingrelations each 1-to-many or two 1-to-1? - Is there a better way to set up the relations for this constellation?
- If not, how do I get the structure to be less hacky and more rails-y?
Not-really-UML:

Code:
In app/models/user.rb
# Exchanges
has_many :initiated_exchanges, class_name: "Exchange",
foreign_key: "init_user_id"
has_many :requested_exchanges, class_name: "Exchange",
foreign_key: "req_user_id"
# Ratings
has_many :init_user_ratings, through: :initiated_exchanges
has_many :req_user_ratings, through: :requested_exchanges
And in app/models/exchange.rb
# Users
belongs_to :init_user, class_name: "User",
foreign_key: "init_user_id"
belongs_to :req_user, class_name: "User",
foreign_key: "req_user_id"
# Ratings
belongs_to :init_user_rating, class_name: "Rating",
foreign_key: "init_user_rating_id"
belongs_to :req_user_rating, class_name: "Rating",
foreign_key: "req_user_rating_id"
In app/models/rating.rb
def exchange
Exchange.find_by("init_user_rating_id=? or req_user_rating_id=?", id, id)
end
From app/db/schema.rb
create_table "exchanges", force: :cascade do |t|
t.integer "init_user_id", null: false
t.integer "req_user_id", null: false
t.integer "init_user_rating_id"
t.integer "req_user_rating_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "ratings", force: :cascade do |t|
t.integer "rating"
t.text "text", limit: 1000
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end