在Rails中选择正确的模型关联4

时间:2015-08-07 08:41:55

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

我无法确定哪种类型的关联最适合我的应用程序。我有以下模型:FirmClientCase

公司处理许多案例。每个案例都可以分配一个或多个 客户端。因此,我最初的方法是:

class Firm < ActiveRecord::Base
   has_many :cases
   has_many :clients
end

class Case < ActiveRecord::Base
   belongs_to :firm
   has_many :clients
end

class Client < ActiveRecord::Base
   belongs_to :firm
   has_many :cases
end

但我认为有些事情是不对的。我在想has_many :through协会会更好,但我不确定。

2 个答案:

答案 0 :(得分:2)

假设案件永远不属于另一家公司:

class Firm < ActiveRecord::Base
    has_many :clients
    has_many :cases, through: :clients
end

class Client < ActiveRecord::Base
    belongs_to :firm
    has_and_belongs_to_many :cases
end

class Case < ActiveRecord::Base
    has_and_belongs_to_many :clients
end

迁移联接表 rails g migration CreateJoinTableCaseClient case client

答案 1 :(得分:2)

  

Rails指南说“如果你需要在连接模型上进行验证,回调或额外的属性,你应该使用has_many:”。正如伟大的编码哲学家Avi Flombaum曾经躲过的那样,你怎么可能知道你的连接模型在申请过程的早期就不会有其他用途。无论您处于开发阶段,将来都无法看到您不需要扩展连接表。

     
    

Why You Don’t Need Has_and_belongs_to_many Relationships

  

解决这个问题:

# models/firm.rb
class Firm < ActiveRecord::Base
    has_many :clients
    has_many :cases, through: :clients
end

# models/client.rb
class Client < ActiveRecord::Base
    belongs_to :firm
    has_many :client_cases
    has_many :cases, through: :client_cases
end

# models/case.rb
class Case < ActiveRecord::Base
    has_many :client_cases
    has_many :clients, through: :client_cases
end

# models/client_case.rb
class ClientCase < ActiveRecord::Base
    belongs_to :client
    belongs_to :case
end

更新

你的问题必须在其他地方;我能够在终端中创建以下内容而没有任何错误。

f = Firm.create name: 'Magical Group' # => #<Firm id: 1...
b = f.clients.create name: 'Billy' # => #<Client id: 1...
m = f.clients.create name: 'Megan' # => #<Client id: 2...
c = Case.create name: 'Billy & Megan are getting married!' # => #<Case id: 1...
b.cases << c # => #<ActiveRecord::Associations::CollectionProxy
m.cases << c # => #<ActiveRecord::Associations::CollectionProxy
f.cases.count # => 2
f.cases.uniq.count # => 1

我提供了数据库架构,请确保您的类似:

ActiveRecord::Schema.define(version: 20150813173900) do

    create_table "cases", force: :cascade do |t|
        t.string   "name"
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
    end

    create_table "client_cases", force: :cascade do |t|
        t.integer  "client_id"
        t.integer  "case_id"
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
    end

    add_index "client_cases", ["case_id"], name: "index_client_cases_on_case_id"
    add_index "client_cases", ["client_id"], name: "index_client_cases_on_client_id"

    create_table "clients", force: :cascade do |t|
        t.string   "name"
        t.integer  "firm_id"
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
    end

    add_index "clients", ["firm_id"], name: "index_clients_on_firm_id"

    create_table "firms", force: :cascade do |t|
        t.string   "name"
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
    end

end