Почему моя ассоциация «многие ко многим через» терпит неудачу? - PullRequest
0 голосов
/ 06 января 2012

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

user.rb:

has_many :subscriptions
has_many :providers, :through => :subscriptions

has_many :followings, :class_name => "Subscription"
has_many :followers, :through => :followings

subscription.rb

belongs_to :provider, :class_name => 'User', :foreign_key => "provider_id"
belongs_to :follower, :class_name => 'User', :foreign_key => "follower_id"

users_controller.rb

69 def follow
70   logger.debug params.to_yaml
71   @user = User.find(params["user_id"])
72   logger.debug @user.to_yaml
73   if current_user.providers << @user
74     flash[:notice] = "Subscribed"
75   else
76     flash[:error] = "Unable to subscribe."
77   end
78 end

Это ошибка при вызове follow:

ActiveRecord::UnknownAttributeError (unknown attribute: user_id):
  app/controllers/users_controller.rb:73:in `follow'

Я проверил, что я запускал rake db: migrate - в таблице подписки есть два поля provider_id и follower_id. Может кто-нибудь помочь мне с ошибкой и объяснить, почему он ищет атрибут 'user_id'?

Обновление:

show.html.erb:

<%= button_to "Subscribe", user_follow_path(@user), :remote => true %>

routes.rb:

resources :users do
  resources :locations
  resources :saved_events
  resources :saved_locations
  post "follow"
end

рейковые маршруты | grep follow:

user_follow POST     /users/:user_id/follow(.:format)                    {:action=>"follow", :controller=>"users"}

Ответы [ 2 ]

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

Используя Учебное пособие Майкла Хартла в качестве руководства, я придумал это решение, которое исправляет модель данных так, чтобы функции сбора работали так, как они должны.удалите внешние ключи в модели подписки.

subscription.rb:

attr_accessible :provider_id
belongs_to :provider, :class_name => 'User'
belongs_to :follower, :class_name => 'User'

Добавьте внешние ключи для подписок и обратных_подписок в модели пользователя.

has_many :subscriptions, :foreign_key => "subscriber_id", :dependent => :destroy
has_many :subscribed_to, :through => :subscriptions, :source => :provider

has_many :reverse_subscriptions, :class_name => "Subscription", :foreign_key => "provider_id", :dependent => :destroy
has_many :followers, :through => :reverse_subscriptions

Я также добавил вспомогательные методы в модель пользователя.

user.rb:

def following?(provider)
  subscriptions.find_by_provider_id(provider)
end

def follow!(provider)
  subscriptions.create!(:provider_id => provider.id)
end

def unfollow!(provider)
  subscriptions.find_by_provider_id(provider).destroy
end

Затем в контроллере мы можем вызвать follow!или отписаться!

user_controller.rb:

...
current_user.unfollow!(@user)
...
current_user.follow!(@user)
...
0 голосов
/ 06 января 2012

Причина, по которой вы получаете ошибку, состоит в том, что когда вы звоните << в коллекции провайдеров, пользователь не знает, что он должен быть подписчиком.Так что в основном говорится: «Я пользователь, добавь меня в эту коллекцию провайдеров!»вместо "Этот парень будет следовать за мной, я теперь провайдер, а он последователь"

Самый простой ответ может быть просто сделать

user.rb:

def follow(other_user)
  Subscription.create(:provider => other_user, :follower => self)
end

users_controller.rb

def follow
  @user = User.find(params["user_id"])
  if current_user.follow(@user)
    flash[:notice] = "Subscribed"
  else
    flash[:error] = "Unable to subscribe."
  end
end
...