【问题标题】:has_many through same table Railshas_many 通过同一张表 Rails
【发布时间】:2017-05-20 13:21:35
【问题描述】:

我想创建一个允许“用户”关注其他用户的 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

【问题讨论】:

    标签: ruby-on-rails has-many-through


    【解决方案1】:

    我假设您有一个 current_user 方法返回登录用户 - 就像 Devise 提供的一样。如果没有,您需要先设置身份验证。

    创建嵌套路由:

    # config/routes.rb
    resources :users, only: [] do
      resources :followings, only: [:create, :destroy], shallow: true
    end
    

    为关注添加验证以避免重复:

    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 视图。

    <% 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-10
      • 1970-01-01
      • 1970-01-01
      • 2014-11-28
      • 2011-11-19
      相关资源
      最近更新 更多