has_many: через Rails 3.1.1 - PullRequest
       1

has_many: через Rails 3.1.1

0 голосов
/ 11 января 2012

Обновлен вопрос, поскольку оригинал был более упрощенным, спасибо Аарону Маклеоду, также известному как AGMCLEOD, за помощь в выделении этого


Моя проблема в том, что я не могу заставить его работать, а заставляю работать так, как я хочу.

Проблема

Представьте себе 3 модели, компанию, филиал и контакт, они связаны друг с другом через модель CompanyContacts или справочную таблицу.

Таблица company_contacts выглядит следующим образом:

+------------+-----------+------------+
| company_id | branch_id | contact_id |
+------------+-----------+------------+

и мои идеальные утверждения для связи контакта с филиалом и компанией должны быть:

update company_contacts set contact_id = x where branch_id = y AND company_id = z

Итак, вопрос: как это возможно при использовании ActiveRecord? Вы создаете собственные методы, чтобы установить его за один раз?

Что у меня есть в моих моделях

КомпанияКонтакт Модель

belongs_to :company, :class_name => "Company", :foreign_key => :company_id
belongs_to :branch,  :class_name => "Branch",  :foreign_key => :branch_id
belongs_to :contact, :class_name => "Contact", :foreign_key => :contact_id

Фирменная модель

has_many :company_contacts
has_many :branches,  :through => :company_contacts, :source => :branches
has_many :contacts,  :through => :company_contacts, :source => :contacts 

Филиал Модель

has_many :company_contacts
has_many :companies, :through => :company_contacts, :source => :companies
has_many :contacts,  :through => :company_contacts, :source => :contacts 

Я бы хотел сделать следующее, но это невозможно

has_one :company, :through => :company_contacts, :source => :company

Конечно, я мог бы смоделировать это

def branch
  Branch.companies.first
end

Модель контакта

has_many :company_contacts
has_many :branches, :through => :company_contacts, :source => :branches
has_many :companies, :through => :company_contacts, :source => :companies

Опять же, в идеале, я бы хотел иметь филиал has_one и компанию has_one

Мое текущее решение при создании контакта и << к ветви приводит к созданию двух строк </p>

+------------+-----------+------------+
| company_id | branch_id | contact_id |
+------------+-----------+------------+
| 1          | 1         | nil        |
+------------+-----------+------------+
| nil        | 1         | 1          |
+------------+-----------+------------+

Когда, на самом деле, я бы хотел добиться:

+------------+-----------+------------+
| company_id | branch_id | contact_id |
+------------+-----------+------------+
| 1          | 1         | 1          |
+------------+-----------+------------+

Единственный способ сделать это - создать собственный метод

Я буду продолжать пытаться решить мою проблему и опубликовать свои выводы С нетерпением ждем ваших ответов

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 11 января 2012

хорошо после чертовски много копания после публикации вопроса я наткнулся на этот удивительный ответ на что-то подобное.Zetetic предоставил очень подробный ответ, и я немного подробнее прочитал, как решить эту проблему.

Сначала вдохновение: has_many: через множественные отношения has_one?

Теперь ответ:

В методе создания в ContactController волшебная 1 строка кода:

@contact.company_contacts.build(:company_id => @company.id, :branch_id => @branch.id)

Итак, в полном объеме в методе создания ContactController:

# fetch the branch and company ids first

@contact = Contact.new(params[:contact])
@contact.company_contacts.build(:company_id => @company.id, :branch_id => @branch.id)
@contact.save

и он делает именно то, чего я хотел достичь:

INSERT INTO "company_contacts" ("branch_id", "company_id", "contact_id") VALUES (?, ?, ?)  [["branch_id", 2], ["company_id", 4], ["contact_id", 12]]

Уф - у меня ушло некоторое время по какой-то причине и, кажется, это так просто смотреть на это!

0 голосов
/ 11 января 2012

Чтобы решить эту проблему, вы можете сделать что-то вроде следующего.Предполагая, что вы передаете идентификатор филиала и идентификатор компании через форму, или если он уже есть в URL.

def create
  @contact = Contact.new(params[:contact])
  if @contact.save
    cc = CompanyContact.new(:contact_id => @contact.id, :branch_id => params[:branch_id], :company_id => params[:company_id])
    cc.save
    redirect_to contacts_url, :notice => "Contact saved"
  else
    render :action => "new"
  end
end

Возможно, вам придется настроить имена параметров и тому подобное, но это должно работать.Поскольку это трехстороннее соединение, я не уверен, есть ли способ построить его прямо на контактном объекте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...