has_many через и частичные - PullRequest
       12

has_many через и частичные

0 голосов
/ 02 апреля 2010

У меня есть модель User, модель Post и модель Interest.


User has_many posts through interests

User has_many interests

Post has_many users through interests

Post has_many interests

Interest belongs to Post

Interest belongs to User  

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

class ApplicationController < ActionController::Base
  before_filter :login_from_cookie
  before_filter :find_user_interests
  helper :all # include all helpers, all the time
  session :session_key => '_blah_session'

  include AuthenticatedSystem   

  def find_user_interests
    @user_interests = current_user ? current_user.interests : []  
    true
  end

end

Application.html.erb имеет следующее:

<%= render :partial => "users/interests", :object => @user_interests %>

_interests.html.erb частично выглядит следующим образом:

ul
  <% unless current_user.nil? then -%>  
    <% @user_interests.each do |interest| -%>
      li<%= interest.post.title %>/li
    <% end %>
  <% end -%>   
/ul    

Учитывая все это, когда я на localhost: 3000 / posts / 1, мое частичное обнаружение нормально, но когда на localhost: 3000 / posts я получаю ошибку undefined method 'title' for nil:NilClass, таким образом, ошибка в строке li<%= interest.post.title %>/li, показанной выше _interests.html.erb частичное.

Какого черта будет проблема?

ТИА

1 Ответ

2 голосов
/ 02 апреля 2010

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

class Post < ActiveRecord::Base
  has_many :interests, :dependent => :destroy
end

А пока вы должны очистить базу данных от детей-сирот.

Редактировать: Вы утверждаете, что это уже было в вашей модели, но если это было так, неясно, как вы могли бы иметь потерянные проценты, как указывает ошибка. Может быть, он был создан до того, как вы добавили зависимое предложение? Опять же, удалите сирот с помощью SQL и попробуйте снова. Если проблема появляется позже, вы должны удалить где-нибудь без обратных вызовов.

Относительно вашего размера проблемы. Вы могли бы использовать current_user.interests.count. Это связано с магией с ассоциациями Rails. count - это специальный метод в ассоциации Rails, который запускает SQL. length - это просто метод массива, сообщающий вам, сколько элементов в массиве. В Rails-ассоциациях есть несколько специальных методов, но остальные они прозрачно проходят через объект массива.

Дальнейшие критические замечания: когда вы передаете :object => @user_interests, вы устанавливаете переменную с именем партиала. Таким образом, вы можете ссылаться на локальную переменную interests в частичном. Однако вы ссылаетесь на @user_interests, поэтому передача объекта не обязательна. При прочих равных условиях передача объекта и использование локальной переменной, вероятно, лучше (это более явно, скорее стиль функционального программирования), но в этом случае вы не используете это.

Наконец, по стилю, я могу ошибаться, поскольку у меня нет полного контекста, но в целом я бы поместил условие logged_in в шаблон, а не устанавливал user_interests в пустой массив, если вошедший пользователь не зарегистрирован. Это позволит вам ссылаться на current_user.interests.count в шаблоне и независимо устанавливать интересы, которые будут отображаться (например, для нумерации страниц) в @user_interests.

...