Как найти нужный объект в контроллере Rails на основе двух переменных? - PullRequest
0 голосов
/ 16 мая 2010

У меня есть система из трех таблиц: компании, клиенты и матчи. Совпадения включают, например, личные заметки, которые каждая сторона делает о другой, и некоторые параметры, которые они могут установить относительно другой.

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

# Customers Controller
def show
  @customer = Customer.find(params[:customer])
  @matchings = @customer.matchings.find... #corrected
  @company = Company.find(params[:company])
end

Очевидно, @matchings является неполным. Учитывая, что @matchings имеет поля customer_id и company_id, как мне найти подходящую запись? Спасибо!

------ UPDATE ------

Это было действительно полезно, спасибо, jdl!

Компания задает клиенту некоторые вопросы, а клиент отвечает. Вопросы хранятся в Вопросе, а ответы хранятся в MatchingAnswer. Чтобы уточнить структуру базы данных:

# models, aggregated
1st set of connections:
  Company has_many :questionlists (QuestionList belongs_to :company)
  QuestionList has_many :questions (Question belongs_to :question_list)
  Question has_many :matching_answers (MatchingAnswer belongs_to :question)
2nd set of connections:
  Company has_many :matchings (Matching belongs_to :company)
  Matching has_many :matching_answers (MatchingAnswer belongs_to :matching)

Помните, что соответствие - это сквозная таблица между Компанией и Клиентом. Я должен показать компании каждый вопрос, который задала компания, и каждый ответ на этот вопрос от конкретного клиента.

# QuestionLists controller
@questions = @questionlist.questions.find(:all)
@matchinganswers = @matching.matching_answers.find(:all, :conditions => ["question_id= ?", @question.id])

... за исключением того, что условие должно удовлетворяться каждым идентификатором вопроса, предоставленным моим циклом ВНУТРИ представления. Давайте посмотрим на вид.

# view
<% @questions.each do |q| %>
  <li><%= q.question %></li>
  <li><% q.matching_answers.each do |a| %>
    <%= a.answer %>
    <% end %></li>
<% end %>

Я знаю, что это пронизано дырами ... Я просто не смог их правильно заполнить. Как я могу сделать цикл под каждым вопросом, чтобы увидеть ответы, которые клиент дал на этот вопрос? Спасибо большое, ребята, это потрясающая группа. :)

------ ОБНОВЛЕНИЕ № 2 ------

Проблема не во вложении, а в том, что q.matching_answers дает мне КАЖДЫЙ ответ, который каждый клиент когда-либо давал на вопрос q. Мне нужно сгенерировать только те match_answers, которые вытекают из определенного вопроса и соответствуют нашему match_id (@ match.id). Модель MatchingAnswer содержит поле match_id, поэтому каждый ответ уникален для конкретного соответствия между клиентом и компанией. Моя проблема заключается в настройке правильных параметров, поэтому я получаю только те сопоставляющие ответы, которые удовлетворяют:

MatchingAnswer.matching_id = @matching.id
MatchingAnswer.question_id = @question.id

Проблема в том, что, хотя я действительно вычисляю @ match.id в контроллере QuestionLists, у меня есть доступ только к @question_list (есть только один) и @questions (все вопросы, принадлежащие этому списку). Я подумал, что должен сделать цикл внутри представления, в котором говорится, что для каждого вопроса задайте те вопросы, которые соответствуют MatchingAnswer.question_id = [this question.id]. Я пытался сделать это с помощью указанного выше гнезда, но, как вы можете сказать, оно не дает нам два параметра, которые нам нужны.

1 Ответ

2 голосов
/ 16 мая 2010

Ответ на оригинальный вопрос о моделях.

Ваши модели могут сделать все это за вас, если вы правильно их настроите.

# company.rb
class Company < ActiveRecord::Base
  has_many :matchings
  has_many :customers, :through => :matchings
end

# customer.rb
class Customer < ActiveRecord::Base
  has_many :matchings
  has_many :companies, :through => :matchings
end

# matching.rb
class Matching < ActiveRecord::Base
  belongs_to :company
  belongs_to :customer
end

Тогда в вашем контроллере, если выЕсли у вас есть @customer, вы можете легко получить matchings или companies.

@customer = # however you figure out which customer you care about at the moment.
@companies = @customer.companies
@matchings = @customer.matchings

Обратное также работает: то есть @company.customers и т. д.

Если вы хотитенайти все подходящие объекты для данной комбинации клиента и компании, это сделает это.

@matchings = Matching.find(:all, :conditions => ["company_id = ? AND customer_id = ?", @company.id, @customer.id])

Я понятия не имею, что такое @candidate в вашем вопросе.Я предполагаю, что это опечатка.

Если вы хотите немного очистить свой контроллер, вы можете вставить логику поиска в named_scope при сопоставлении.

class Matching < ActiveRecord::Base
  belongs_to :company
  belongs_to :customer

  named_scope :for_company_and_customer, lambda {|comp, cust| {:conditions => {:company_id => comp, :customer_id => cust}}}
end

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

@matchings = Matching.for_company_and_customer(@company, @customer)

Ответ на обновленный вопрос о представлениях.

Я предполагаю, что с вашими моделями все в порядке, и вы можете получить нужные данные.Вы должны иметь возможность просто вкладывать свои списки HTML, чтобы получить то, что вы ищете.Очевидно, что есть более причудливые способы сделать это.

<% @questions.each do |q| %>
  <li><%= h q.question %>
    <ul>
      <% q.matching_answers.each do |a| %>
        <li><%= h a.answer %></li>
      <% end %>
    </ul>
  </li>
<% end %>

(обратите внимание на использование метода h . Вы хотите избежать пользовательских данных, чтобы избежать потенциальных проблем безопасности.)

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