Pages#profile中的NoMethodError

时间:2017-07-10 18:40:16

标签: ruby-on-rails ruby

我正致力于构建类似Twitter的示例应用,但我仍然坚持创建以下方法。我创建了一个关系模型和完成任务所需的类,但是当我加载页面时,我收到错误&#34; NoMethodError&#34;在这一行:<%= form_for(current_user.active_relationships.build, remote: true) do |f| %>

我在个人资料页面上渲染表单,如下所示:

<%= render '/components/follow_button', :user => User.find_by_username(params[:id]) %>

以下是表格:

<% if current_user.id != user.id %>
<div class="col s12">
    <div class="panel panel-default">
        <% if !current_user.following?(user) %>
            <%= form_for(current_user.active_relationships.build, remote: true) do |f| %>
                <div><%= hidden_field_tag :followed_id, user.id %></div>
                <%= f.submit "Follow", class: "btn btn-primary" %>
            <% end %>
        <% else %>
            <%= form_for(current_user.active_relationships.find_by(followed_id: user.id),
                html: { method: :delete }) do |f| %>
                <%= f.submit "Unfollow", class: "btn" %>
            <% end %>
        <% end %>
    </div>
</div>

<% end %>

User.rb:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  validates_uniqueness_of :email, :case_sensitive => false
  validates_uniqueness_of :username, :case_sensitive => false

    has_many :posts, dependent: :destroy
    has_many :active_relationships, class_name: "Relationship", foreign_key: "follower_id", dependent: :destroy
    has_many :passive_relationships, class_name: "Relationship", foreign_key: "followed_id", dependent: :destroy

    has_many :following, through: :active_relationships, source: :followed
    has_many :followers, through: :passive_relationships, source: :follower


    def follow(other)
      active_relationships.create(followed_id: other.id)
    end

    def unfollow(other)
      active_relationships.find_by(followed_id: other.id).destroy
    end

    def following?(other)
      following.include?(other)
    end

end

Relationship.rb

class Relationship < ActiveRecord::Base
    belongs_to :follower, class_name: "User"
    belongs_to :followed, class_name: "User"
    validates :follower_id, presence: true
    validates :followed_id, presence: true
end

RelationshipsController:

class RelationshipsController < ApplicationController

    def create
        user = User.find(params[:followed_id])
        current_user.follow(user)
        redirect_to(:back)
    end

    def destroy
        user = Relationship.find(params[:id]).followed
        current_user.unfollow(user)
        redirect_to(:back)
    end
end

任何帮助都非常赞赏。

编辑:以下Routes.rb中使用的方法

devise_for :users
  resources :users do
    member do
      get :following, :followers
    end
  end

1 个答案:

答案 0 :(得分:2)

form_for文档中,它最终谈到了以资源为导向的风格&#39;形式

  

在刚才显示的示例中,虽然没有明确指出,但我们仍然需要使用:url选项来指定表单的发送位置。然而,如果传递给form_for的记录是资源,则它可以进一步简化,即它对应于一组RESTful路由,例如,使用config / routes.rb中的resources方法定义。在这种情况下,Rails将简单地从记录本身推断出适当的URL

<%= form_for(Post.new) do |f| %>
  ...
<% end %>
  

等同于:

<%= form_for @post, as: :post, url: posts_path, html: { class: "new_post", id: "new_post" } do |f| %>
  ...
<% end %>

查看您的代码,因为您没有将:url选项传递给form_for并且您正在传递模型的实例,所以它假设您的模型已在路径文件中配置使用resources :relationships生成一些命名的路由助手,例如relationships_path,它所抱怨的方法就丢失了。

要解决您的问题,您需要将form_for :url传递给控制器​​所在的位置以及应该发布到的位置,或者更新您的路线以使用resources :relationships。您可以阅读有关resources routing here的更多信息。如果你添加

resources :relationships, only: [:create, :destroy]

devise_for区块之外,您最终将获得2条新路线

       Prefix Verb   URI Pattern                  Controller#Action
relationships POST   /relationships(.:format)     relationships#create
 relationship DELETE /relationships/:id(.:format) relationships#destroy

以及您的2个relationships_path标记将要查找的指定助手relationship_pathform_for

在更改config / routes.rb文件后,不要忘记重新启动服务器,以确保rails选择它们。