从Active Record中的两个可连接表中检索对象

时间:2012-03-05 14:14:31

标签: ruby postgresql activerecord

我有一种情况,我有一个SQL表,几乎是'父母'其他人。 在下面的示例中,最容易想象的是,不同类型的客户端(需要存储不同的数据字段)都具有唯一的客户端ID。

CREATE TABLE clients (
  id serial NOT NULL,
  internal_ref character varying,
  address character varying,
  telephone_no character varying,
  CONSTRAINT pkey_clients PRIMARY KEY (id),
  CONSTRAINT uniq_clients_internal_ref UNIQUE (internal_ref)
)

CREATE TABLE partnerships (
  id serial NOT NULL,
  clients_id integer,
  name character varying,
  CONSTRAINT pkey_partnerships PRIMARY KEY (id),
  CONSTRAINT fkey_partnerships_clients_id FOREIGN KEY (clients_id)
    REFERENCES clients(id) MATCH FULL
      ON UPDATE NO ACTION
      ON DELETE NO ACTION
)

CREATE TABLE individuals (
  id serial NOT NULL,
  clients_id integer,
  forename character varying,
  surname character varying,
  CONSTRAINT pkey_individuals PRIMARY KEY (id),
  CONSTRAINT fkey_individuals_clients_id FOREIGN KEY (clients_id)
    REFERENCES clients(id) MATCH FULL
      ON UPDATE NO ACTION
      ON DELETE NO ACTION
)

我是Active Record的新手,不知道如何(或者如果)我可以优雅地实现它,这样我就可以找到一个企业并获得加入的客户数据。

目前我正在尝试:

class Client < ActiveRecord::Base
end
class Partnership < ActiveRecord::Base
  has_one :clients
end

output = Partnership.find(:all) # I only have one row in both tables, which is also joinable
p output # => [#<Partnership id: 1, name: "PART1", clients_id: 1>]

我还需要output来获取可加入的数据,例如internal_refaddress等。我该怎么做?

1 个答案:

答案 0 :(得分:3)

易。您的“子”模型belongs_to“父”模型可以has_onehas_many“孩子”

型号:

# app/models/client.rb
class Client < ActiveRecord::Base
  has_one :partnership
  has_one :individual
end

# app/models/pertnership.rb
class Partnership < ActiveRecord::Base
  belongs_to :client
end

# app/models/individual.rb
class Individual < ActiveRecord::Base
  belongs_to :client
end

控制器:

@output = Partnerships.all

如果您每次尝试访问客户端时都不想进行其他查询,请使用预先加载:

@output = Partnerships.includes(:client).all

或者急切地加载客户和个人:

@output = Partnerships.includes(:client => :individual ).all

然后,在您的视图中,您可以轻松访问引用的客户端甚至客户端中引用的个人。

<% @output.each do |partnership| %>
  <%= partneship.client.internal_ref %>
  <%= partneship.client.address %>
  <%= partneship.client.individual.forname %>
<% end %>