Rails 4.2中的关系:1对多或2对1

时间:2015-06-15 10:34:00

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord rails-activerecord

我将如何描述它应该有效:

User Alice 可以与另一个Exchange Bob 发起User。所以Alice是此Exchange发起用户,而Bob是请求的用户

User可以包含多个Exchange

Exchange有一个initiating_user和一个requested_user。 我不确定这是1对1还是1对多的关系,因为两者都是User,但是没有用相同的名称来解决。

Exchange只有两个Rating,但问题与之前相同。我不知道这是1对1还是1对多的关系。 initiating_userrequested_user中的每一个都可以生成Rating。 那么分别是initiating_user_ratingrequested_user_rating

Rating只属于一个Exchange

我的问题:

我几乎可以肯定,有一种比我现在使用的更简单的方法,可能只是使用ActiveRecord关系。 它目前有效,但我对此并不满意。

所以我想我的问题是:

  • 这些initiating_user / requested_userinitiating_user_rating / requested_user_rating关系是1对多吗? 或两个1比1?
  • 有没有更好的方法来建立这个星座的关系?
  • 如果没有,我如何让结构变得更少hacky和更多rails-y?

不会-真-UML:

UML of how it should work

代码:

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

并在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"

app/models/rating.rb

def exchange
  Exchange.find_by("init_user_rating_id=? or req_user_rating_id=?", id, id)
end

来自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

0 个答案:

没有答案