首页 > 解决方案 > Rails 简单形式未定义的局部变量或方法“资源”

问题描述

我有 2 步调查,1 步提交新记录SurveyResults和 redirect_to 第二步,User根据用户选择的答案(单选按钮)更新模型。为了处理第二步,我controllers/users/UserExperienceLevelsController使用以下更新方法创建了新的:

def update
  if current_user.update(experience_level: users_user_experience_level_params)
    redirect_to root_path, notice: 'User experience level was successfully submitted.'
  else
    render :edit
  end
end

private

def users_user_experience_level_params
  params.fetch(:users_user_experience_level).permit(:experience_level)
end

有意见:

<%= simple_form_for(resource, as: resource_name, url: edit_users_user_experience_level_path(resource_name), html: { method: :put }) do |f| %>
  <%= f.error_notification %>
  <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>

  <%= f.input :experience_level, collection: User::USER_EXPERIENCE_LEVEL, as: :radio_buttons %>
  <%= f.button :submit %>
<% end %>

但我收到一个错误:

NameError in Users::UserExperienceLevels#edit
undefined local variable or method `resource' for #<ActionView::Base:0x0000000000bbd0>

[编辑]

路线:

  namespace :users do
    resources :user_experience_levels, only: [:edit, :update]
  end

标签: ruby-on-rails

解决方案


您的视图中缺少两个可能应该从控制器发送的局部变量。局部变量可以通过locals选项传递给视图:

render :edit, 
       locals: { resource: current_user, resource_name: :user }

它没有很好的文档记录,但是您可以在渲染视图时传递局部变量,而不仅仅是局部变量。此技术允许您绕过使用控制器实例变量将数据传递给视图。

另一种选择是从您的控制器声明辅助方法:

module Users
  class UserExperienceLevelsController 

    # ...

    def resource
      current_user
    end

    helper_method :resource

    def resource_name
      :users_user_experience_level
    end
  
    helper_method :resource_name
  end
end

这会将这些方法暴露给视图。如果您想使用继承或其他形式的组合来设置数据,这很有用。


推荐阅读