2

我刚刚完成了 Ruby on Rails 3 教程。最后一章相当复杂。整本书的教程基本上创建了一个用户可以发布微博的网站。此外,每个用户都可以关注任何其他用户,然后以下用户的微博将显示在原始用户的微博提要中。

我的问题与为什么RelationshipsController 中的create 操作的params 变量包含一个二维数组有关。

这是代码。

用户

class User < ActiveRecord::Base
  attr_accessible :email, :name, :password, :password_confirmation
  has_secure_password
  has_many :microposts, dependent: :destroy
  has_many :relationships, foreign_key: "follower_id", dependent: :destroy
  has_many :followed_users, through: :relationships, source: :followed
  has_many :reverse_relationships, foreign_key: "followed_id", 
      class_name: "Relationship", dependent:   :destroy
  has_many :followers, through: :reverse_relationships, source: :follower
end

微博

class Micropost < ActiveRecord::Base
  attr_accessible :content
  belongs_to :user
end

关系

class Relationship < ActiveRecord::Base
  attr_accessible :followed_id

  belongs_to :follower, class_name: "User"
  belongs_to :followed, class_name: "User"
end

我认为这是创建二维参数变量的代码(但为什么?)

<%= form_for(current_user.relationships.build(followed_id: @user.id), remote: true) do       
    |f| %>
  <div><%= f.hidden_field :followed_id %></div>
  <%= f.submit "Follow", class: "btn btn-large btn-primary" %>
<% end %>

关系控制器

class RelationshipsController < ApplicationController  
  def create
    @user = User.find(params[:relationship][:followed_id])
    current_user.follow!(@user)
    respond_to do |format|
      format.html { redirect_to @user }
      format.js
    end
  end
end

所以也许我只是回答了我自己的问题,但我从未见过 params 变量的二维数组。有人可以对此有所了解吗?

哦,也许我也应该发布我的 routes.rb 文件:

SampleApp::Application.routes.draw do
  resources :users do
    member do
      get :following, :followers
    end
  end
  resources :sessions, only: [:new, :create, :destroy]
  resources :microposts, only: [:create, :destroy]
  resources :relationships, only: [:create, :destroy]

  root to: 'static_pages#home'
end

谢谢,迈克

4

1 回答 1

4

简短的回答:

这不是一个二维数组,它是一个嵌套的关联数组。您使用它的原因是为了获得您真正想要的领域。


长答:

教程假设:当用户点击关注按钮时,目标是调用current_user.follow!(other_user). 我将引导您了解代码是如何实现这一点的。所有的魔法都在关系控制器和视图中的 form_for 函数中。

首先,您为新的关系制作表格。因为它是一个嵌套资源,所以您通过关联来构建它。

current_user.relationships.build

但是一个只对应一个用户的全新的关系对象并没有多大意义。相反,传入一个关联的值数组来初始化对象。在这种情况下,其他用户的 id。因此,您将要构建的关系对象的 :followed_id 属性分配给 @user.id 或您尝试关注的用户。

current_user.relationships.build(followed_id: @user.id)

当您对一个对象进行 form_for 时,您可以访问该对象的属性。在这种情况下,如果我们查看关系模型,则只有 :followed_id 是可访问的。

class Relationship < ActiveRecord::Base
  attr_accessible :followed_id

最后,我们需要捕获表单提交中的followed_id,因为表单的目标是能够current_user.follow!(other_user)在点击关注按钮时调用。所以我们将followed_id作为隐藏字段传入,这样它就可以在params控制器中访问,但用户在视图本身中也看不到它。

  <%= f.hidden_field :followed_id %>

最后,当单击按钮时,因为表单是针对新的关系对象的,所以为关系控制器调用创建操作。在那里,要访问与表单对应的关系对象,您的操作方式与教程中的其他表单相同 -

params[:relationship]

但是你不想要关系对象,你想要跟随的用户对象,这样你就可以调用follow!. 这很简单。只需从 id 中找到数据库中的用户即可。如何获得followed_id?它是表单中关系对象的一个​​属性。

params[:relationship][:followed_id]

我认为值得注意的是,当你创建一个新的用户对象时,你使用了 params[:user]。这只是一个关联数组,如果您愿意,可以访问它的字段

params[:user][:name]

希望这是有道理的。它只是一个嵌套的关联数组 Rails 用来跟踪参数,例如提交表单的参数。

于 2012-07-16T17:36:57.787 回答