Ruby中没有方法错误

时间:2011-01-14 09:05:30

标签: ruby-on-rails ajax jquery

我目前有一个Rails应用程序,允许用户拖放网页的某些元素,并根据用户的选择更新应用程序。这是在Rails助手和AJAX的帮助下完成的。但是我一直在Ruby中遇到“NoMethodError”。

NoMethodError in ProjectsController#member_change

undefined method `symbolize_keys' for nil:NilClass

这是被调用的方法。我的追踪表明错误发生在这一行:

before  = u.functions_for(r.authorizable_id)
              u.roles << r unless u.roles.include? r
              u.save
              flag_changed = true
              after = u.functions_for(r.authorizable_id)

这是被称为

的函数
 def member_change
    flag_changed = false
    params['u'] =~ /role_(\d+)_user_(\d+)/
    drag_role_id = $1
    user_id = $2
    params['r'] =~ /role_(\d+)/
    drop_role_id = $1
    if u=User.find(user_id)
      if r=Role.find(drop_role_id)
        if drag_role_id.to_i !=0 and old_r=Role.find(drag_role_id)
          if drag_role_id == drop_role_id #fom A to A => nothing happen
            flash.now[:warning] = _('No Operation...')
          elsif r.authorizable_id == old_r.authorizable_id #the same project?
            old_r.users.delete(u)
            unless old_r.valid?
              flash.now[:warning] = _('Group "Admin" CAN NOT be EMPTY.') 
              old_r.users << u #TODO: better recovery
              member_edit #if flag_changed
              render :action => :member_edit, :layout => 'module_with_flash'
              return
            end
            old_r.save
            r.users << u unless r.users.include? u
            r.save
            flag_changed = true
            before = u.functions_for(r.authorizable_id)
            after = u.functions_for(r.authorizable_id)
            added = after - before
            removed = before - after
            added.each do |f|
              ApplicationController::send_msg(:function,:create,
                                              {:function_name => f.name, 
                                                :user_id => u.id,
                                                :project_id => r.authorizable_id
                                              })
            end
            removed.each do |f|
              ApplicationController::send_msg(:function,:delete,
                                              {:function_name => f.name, 
                                                :user_id => u.id,
                                                :project_id => r.authorizable_id
                                              })
            end
            flash.now[:notice] = _( 'Move User to Group' ) + " #{ r.name }" 
          else
            flash.now[:warning] = 
              _('You can\'t move User between Groups that belong to different Projects.')
          end
        else
          before  = u.functions_for(r.authorizable_id)
          u.roles << r unless u.roles.include? r
          u.save
          flag_changed = true
          after = u.functions_for(r.authorizable_id)
          added = after - before
          added.each do |f|
            ApplicationController::send_msg(:function,:create,
                                            {:function_name => f.name, 
                                              :user_id => u.id,
                                              :project_id => r.authorizable_id
                                            })
          end
          flash.now[:notice] = _( 'Add User into Group' ) + " #{ r.name }"
        end
      else
        flash.now[:warn] = _( 'Group doesn\'t exist!' ) + ": #{ r.name }"
      end 
    else
      flash.now[:warning] = _( 'User doesn\'t exist!' ) + ": #{ u.login }"
    end
    member_edit #if flag_changed
    render :action => :member_edit, :layout => 'module_with_flash'
  end

和用于调用函数的JavaScript

jQuery('#RemoveThisMember').droppable({accept:'.RolesUsersSelection', drop:function(ev,ui){
    if (confirm("This will remove User from this Group, are you sure?"))
    {jQuery.ajax({data:'u=' + encodeURIComponent(jQuery(ui.draggable).attr('id')), success:function(request){jQuery('#module_content').html(request);}, type:'post', url:'/of/projects/11/member_delete'});}
    }, hoverClass:'ProjectRoleDropDelete_active'})

有什么想法吗?

谢谢,

1 个答案:

答案 0 :(得分:0)

重构的时间!可能是大约五分之一的方法。

我怀疑functions_for方法是原因,您可以粘贴其定义吗?

同时,一些一般性建议:

  • 为您的变量指定全名 - user而不是u
  • 你不需要保留一个flag_changed var,检查user.changed? (还有user._new_record?)。
  • 您应该设置路由,这样就不需要对params对象进行正则表达式。
  • 你几乎不应该只有几个级别的条件 - 重构为外部方法。
  • 使用ApplicationController :: send_msg方法(记录?)几乎可以肯定是一种更好的方法。如果您不能使用现有项目,请将其作为ApplicationController中的辅助方法。

我怀疑你最近是从一种低级语言转换过来的?你会发现拥抱ruby约定会为你节省大量的时间和代码。

好奇,_方法做了什么?

希望这有用。