新手问题 rails tutorial 中 ajax 问题

villins · October 28, 2012 · Last by villins replied at October 31, 2012 · 3315 hits

在按照书中代码编写 follow 和 unfollow 按钮时,添加上 ajax 功能后

点击之后就会出现错误

下面为点 unfollow 点击出现的错误信息

Started DELETE "/relationships/1" for 127.0.0.1 at 2012-10-28 20:53:33 +0800
Processing by RelationshipsController#destroy as JS
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"A5HEZNjXLdmCzAO5BXmPXb3X2VkHs8rDpqrw/zErq0k=", "commit"=>"Unfollow", "id"=>"1"}
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
  Rendered users/_unfollow.html.erb (2.2ms)
  Rendered relationships/destroy.js.erb (2.9ms)
Completed 500 Internal Server Error in 6ms

ActionView::Template::Error (Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id):
    1: <%= form_for(current_user.relationships.find_by_followed_id(@user.id),
    2:              :html => { :method => :delete },
    3:              :remote => true) do |f| %>
    4:   <div class="actions"><%= f.submit "Unfollow" %></div>
  app/views/users/_unfollow.html.erb:1:in `_app_views_users__unfollow_html_erb__1917503669697459990_70063164482580'
  app/views/relationships/destroy.js.erb:1:in `_app_views_relationships_destroy_js_erb___120623583448683911_70063171541040'

_destroy.js.erb

$("follow_form").update("<%= escape_javascript(render('users/unfollow')) %>")
$("followers").update('<%= "#{@user.followers.count} followers" %>')

查找了好久,找不出解决方法

还有求点 rails 中用 ajax 的资料

你的 @user 为空,你对它调用 .id 就会报这种错误了,log 里面说的挺清楚的呀:Called id for nil

ls 正解,你不了解的不光是 ajax 还有 rails 甚至 ruby 的基础知识。共勉。

@zzhattzzh @zgm 页面显示信息也是 使用@ user,可以正常显示信息的,为啥还会报这个错误的呢,请明示下

#3 楼 @villins 我猜你的 destroy action 里面没有给 @user 赋值。每次访问服务都会创建新的 controller 实例,所以实例变量是不共享的。

#3 楼 @villins 你 update 了 user/_unfollow.html.erb 要重新生成@user,要不你试试在 destroy action 加上 @user = User.first 异常是不是没了?

@zgm 现在修改些代码,可以执行 follow 和 unfollow 动作,但是 follow 动作点击之后没有转变成 unfollow, 点击 unfollow 出现了

ActionView::Template::Error (undefined method `model_name' for NilClass:Class):
    1: <%= form_for(current_user.relationships.find_by_followed_id(@user.id),
    2:              :html => { :method => :delete },
    3:              :remote => true) do |f| %>
    4:   <div class="actions"><%= f.submit "Unfollow" %></div>
  app/views/users/_unfollow.html.erb:1:in `_app_views_users__unfollow_html_erb___969014464943468430_70171850209980'
  app/views/relationships/destroy.js.erb:1:in `_app_views_relationships_destroy_js_erb___3304318120498350733_25744100'
  app/controllers/relationships_controller.rb:16:in `destroy'

destroy action 代码

def destroy
        @user = Relationship.find(params[:id]).followed
        current_user.unfollow!(@user)
16=》      respond_to do |format|
          format.html { redirect_to @user }
          format.js
        end
    end

#6 楼 @villins form_for(current_user.relationships.find_by_followed_id(@user.id) 这个东西没了。

#7 楼 @zgm 同意楼上,补充一下:使用 form_for 时如果 所传的对象为 nil,一般都会报这样的错误:undefined methodmodel_name' for NilClass:Class`.

@zzhattzzh @zgm 这个错误修正了,但是还是不能局部刷新页面,点了 follow 按钮不能自动变 unfollow,unfollow 按钮不能自动变 follow,之前在做敏捷那本书也是这样

destory.js.erb

$("follow_form").update("<%= escape_javascript(render('users/follow')) %>")
$("followers").update('<%= "#{@user.followers.count} followers" %>')

create.js.erb

$("follow_form").update("<%= escape_javascript(render('users/unfollow')) %>")
$("followers").update('<%= "#{@user.followers.count} followers" %>')
You need to Sign in before reply, if you don't have an account, please Sign up first.