#ruby-on-rails
#ruby-on-rails
Вопрос:
Фильтр с атрибутом другой таблицы (один ко многим) в Rails
Я новичок в rails и в настоящее время работаю над своим классным проектом. У меня есть таблица lead и таблица lead_comments, lead имеет множество lead_comments и lead_comment принадлежат lead, которые я установил.
В модели:
class Lead < ApplicationRecord
has_many :lead_comments
end
class LeadComment < ApplicationRecord
belongs_to :lead
end
В представлении индекса моего интереса я пытаюсь настроить фильтр по дате на основе Update_at в lead_comments, который является атрибутом из другой таблицы:
<div class="date-search">
<%= form_tag leads_path, method: :get do %>
<%= date_field_tag 'date_search[date_from]', @date_search.date_from %>
<%= date_field_tag 'date_search[date_to]', @date_search.date_to %>
<%= submit_tag 'Date Search' %>
<% end %>
</div>
<table>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Phone Number</th>
<th>Last Updated Date</th>
<th colspan="3">Action</th>
</tr>
</thead>
<tbody>
<% @leads.each do |lead| %>
<tr>
<td><%= lead.lead_firstname %></td>
<td><%= lead.lead_lastname %></td>
<td><%= lead.lead_phone %></td>
<td><%= lead.lead_comments.maximum(:updated_at) %></td>
<td><%= link_to 'Detail', lead %></td>
<td><%= link_to 'Edit/Update', edit_lead_path(lead) %></td>
<td><%= link_to 'Remove', lead, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
В моем ведущем контроллере я настроил другой контроллер для поиска потенциальных клиентов:
def index
@date_search = LeadSearch.new(params[:date_search])
@leads = @date_search.scope
end
В моей модели поиска потенциальных клиентов, я полагаю, в чем моя проблема:
class LeadSearch
attr_reader :date_from, :date_to
def initialize(params)
params ||= {}
@date_from = parsed_date(params[:date_from], 30.days.ago.to_date.to_s)
@date_to = parsed_date(params[:date_to], Date.today.to_s)
end
def scope
Lead.lead_comments.maximum(:updated_at).where('updated_at BETWEEN ? AND ?', @date_from, @date_to)
end
private
def parsed_date(date_string, default)
Date.parse(date_string)
rescue ArgumentError, TypeError
default
end
end
Моя таблица lead_comment имеет только один атрибут, который является комментарием, наряду с двумя автоматизированными атрибутами даты, созданными Rails, created_at и updated_at.
Всякий раз, когда я запускаю приложение, я получаю сообщение об ошибке, которое сообщает мне неопределенный метод «lead_comments». Я думал, что я уже установил отношения has_many и belong_to, и это все еще не работает. Может кто-нибудь, пожалуйста, помочь мне и направить меня в правильном направлении? Спасибо за ваше время.
Ответ №1:
вы выполняете Lead.lead_comments, что неправильно. Вы используете имя класса вместо объекта. Должен быть объект ведущей модели.
@lead.lead_comments
Сначала попробуйте выполнить запрос в консоли rails. затем используйте его в контроллере для лучшей перспективы. попробуйте выполнить следующее,
Lead.lead_comments # will give error
вместо этого используйте,
Lead.last.lead_comments # success
Ответ №2:
Проблемы в вашем коде:
Lead.lead_comments
Давайте упростим это: подумайте о lead_comments
как о методе, который, получив преимущество, возвращает свои комментарии. Но нам нужна зацепка. Вот почему вызов на Lead
не работает. Это сработало бы, вызванное для Lead
объекта.
Lead.lead_comments.maximum(:updated_at)
Здесь вы составляете SQL-запрос, хотя ActiveRecord
но вызываете maximum
stop this composition, потому что для этого требуется значение, поэтому вы не можете вызывать что-либо еще после таких методов, как maximum
Давайте заставим ваш код работать
def scope
Lead.where('updated_at BETWEEN ? AND ?', @date_from, @date_to)
end
на ваш взгляд
<td><%= lead.lead_comments.maximum(:updated_at) %></td>
Обратите внимание, что этот код всегда был правильным, потому что вы вызываете lead_comments
ведущий объект.
Я знаю, это выполняет один запрос для каждого Lead
объекта, но заставить его работать только с одним запросом выглядит как другой вопрос