为什么我的多对多关联失败?

发布于 2024-12-25 12:44:40 字数 1593 浏览 0 评论 0原文

我建立了一个类似推特的关注模型。用户都可以互相订阅。尝试创建关系时,我的用户控制器中出现错误。

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

rake 路线 | grep 遵循:

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

I have set up a twitter-like following model. Users can all subscribe to each other. I am getting an error in my users controller when trying to create the relationship.

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

This is the error when I call follow:

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

I have verified that I ran rake db:migrate - the subscription table has two fields provider_id and follower_id. Can anyone help me with the error and explain why it is looking for a 'user_id' attribute?

Update:

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

rake routes | grep follow:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

公布 2025-01-01 12:44:40

使用 Michael Hartl 的教程 作为指导,我想出了这个解决方案,它修复了数据模型,以便收集功能按其应有的方式工作。

使提供者 ID 可访问并删除订阅模型中的外键。

subscription.rb:

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

在用户模型中添加订阅和reverse_subscriptions的外键。

user.rb:

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!或取消关注!

用户控制器.rb:

...
current_user.unfollow!(@user)
...
current_user.follow!(@user)
...

Using Michael Hartl's tutorial as a guide, I came up with this solution, which fixes the data model so that collection functions work as they should.

Make the provider id accessible and remove the foreign keys in the subscription model.

subscription.rb:

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

Add foreign keys for subscriptions and reverse_subscriptions in the user model.

user.rb:

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

I also added helper methods to the user model.

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

Then, in the controller, we can call follow! or unfollow!

user_controller.rb:

...
current_user.unfollow!(@user)
...
current_user.follow!(@user)
...
酒儿 2025-01-01 12:44:40

它给你一个错误的原因是因为当你在提供者集合上调用 << 时,用户不知道它应该是一个追随者。所以它基本上是在说:“我是用户,请将我添加到这个提供商集合中!”而不是“这个人要追随我,我现在是提供者,他是追随者”

最简单的答案可能是只执行

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

The reason it's giving you a error is because the when you call << on the providers collection the user doesn't know it's supposed to be a follower. So it's basically saying, "I'm a user, add me to this collection of providers!" instead of "This guy is going to follow me, I'm now a provider and he's a follower"

The simplest answer may be to just do

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文