我想创建一个允许“用户”关注其他用户的Rails应用。我对更复杂的关系是半新的,并且我试图第一次设置has_many。我希望朋友能够关注其他用户。
这是我的联接表:
class Following < ApplicationRecord
belongs_to :user
belongs_to :follower, class_name: "User"
end
这是我的用户表:
class User < ApplicationRecord
has_many :followings
has_many :followers, through: :followings
end
这是我的架构:
create_table "followings", force: :cascade do |t|
t.integer "user_id"
t.integer "follower_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
我不知道如何设置表单来实际创建关系。在用户视图中,我有这个,但它不起作用。
<%= form_for @following do |f| %>
<%= f.hidden_field :follower_id, :value => @user %>
<%= f.select :user_id, @users.collect { |u| [u.name, u.id] } %>
<%= f.submit %>
<% end %>
正如我所说,我对这种关系很陌生。我需要帮助。我不知道如何通过表单链接记录。
我正在关注本教程:https://teamtreehouse.com/library/what-is-a-hasmany-through-association-in-ruby-on-rails
答案 0 :(得分:0)
我假设你有一个current_user
方法返回登录用户 - 就像Devise提供的那样。如果不是,您需要先设置身份验证。
创建嵌套路线:
# config/routes.rb
resources :users, only: [] do
resources :followings, only: [:create, :destroy], shallow: true
end
向Follow添加验证以避免重复:
class Following < ApplicationRecord
belongs_to :user
belongs_to :follower, class_name: "User"
validates_uniqueness_of :user_id, scope: 'follower_id'
end
向用户添加实用程序方法,以查看他是否关注其他用户:
class User < ApplicationRecord
has_many :followings
has_many :followers, through: :followings
def following?(user)
followings.exist?(user: user)
end
def find_following(user)
followings.find_by(user: user)
end
end
然后我们可以在/users/show.html.erb
视图中添加Follow和Unfollow按钮(它们实际上是表单)。
<% if current_user.following?(@user) %>
<%= button_to "Unfollow", current_user.find_following(@user), method: :delete %>
<% else %>
<%= button_to "Follow", [@user, @user.followings.new] %>
<% end %>
请注意,我们不需要任何表单参数,因为我们使用嵌套路由(POST /users/:user_id/followings
)来传递用户ID(跟随谁),我们从会话中获取当前用户。
然后我们可以设置我们的控制器:
class FollowingsController < ApplicationController
# POST /users/:user_id/followings
def create
@user = User.find(params[:user_id])
@following = Following.new(user: @user, follower: current_user)
if @following.save
redirect_to @user, success: "You are now following #{ @user.name }"
else
redirect_to @user, error: "Could not create following"
end
end
# DELETE /followings/:id
def destroy
@following = Following.find(params[:id])
@following.destroy
redirect_to @following.user, success: "You are no longer following #{ @user.name }"
end
end