为什么我无法成功更新表格?

时间:2019-07-12 13:02:16

标签: ruby-on-rails

我有一个项目,其中用户模型是由设备gem创建的,还有3个角色,它们是用户模型的子级。每个角色都有一个配置文件。而且我想编辑然后更新每个配置文件,但是不能,它不是重定向到更新操作,而是显示

  

找不到UserProfilesController的动作“创建”

这是我的UserProfiles控制器

class UserProfilesController < ApplicationController
  before_action :load_profile, only: %i[show edit update destroy]

  def edit
    @profile = current_user.profile
  end

  def update
    @profile = current_user.profile
    @profile.update(profile_params)
  end

  private

  def load_profile
    @profile = current_user.profile || current_user.build_profile
  end

  def profile_params
    params.require(:profile).permit(:name, :description, :first_name, :last_name, :nickname,
                                    :how_heard, :birthday, :experience_years)
  end
end

营养主义者形式:

    = simple_form_for @profile do |f|
    = f.input :first_name
    = f.input :last_name
    = f.input :work
    = f.input :experience_years
    = f.input :how_heard
    = f.input :birthday, as: :date, start_year: Date.today.year - 90,
                        end_year: Date.today.year,
                        order: [:day, :month, :year]
    = f.submit "Update", class: 'btn btn-primary'

客户表格:

  = simple_form_for @profile do |f|
      = f.input :first_name
      = f.input :last_name
      = f.input :nickname
      = f.input :how_heard
      = f.input :birthday, as: :date, start_year: Date.today.year - 90,
                          end_year: Date.today.year,
                          order: [:day, :month, :year]
      = f.submit "Update", class: 'btn btn-primary'

管理员表单:

= simple_form_for @profile do |f|
      = f.input :first_name
      = f.input :last_name
      = f.input :nickname
      = f.input :how_heard
      = f.submit "Update", class: 'btn btn-primary'

编辑视图:

    %h2 Edit page
- if current_user.instance_of?(Client)
  = render partial: "form_for_client", locals: { profile: @profile }
- elsif current_user.instance_of?(Nutritionist)
  = render partial: "form_for_nutritionist", locals: { profile: @profile }
- else
  = render partial: "form_for_administrator", locals: { profile: @profile }

路线:

devise_for :users, controllers: { registrations: 'user_registrations' }
resource :user_profiles

这也是源html代码的一部分:

<form class="simple_form new_nutritionist_profile" id="new_nutritionist_profile" novalidate="novalidate" action="/user_profiles" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><input type="hidden" name="authenticity_token" value="JUBFG8QwUfsvw55GqFp6tR1dYGrcqflsY+duGt2Y65aDTsKqlINAllD7JP+hqrwRR3otILAhkdN0lH2tYZGlvw==" /><div class="form-group string optional nutritionist_profile_first_name"><label class="form-control-label string optional" for="nutritionist_profile_first_name">First name</label><input class="form-control string optional" type="text" name="nutritionist_profile[first_name]" id="nutritionist_profile_first_name" /></div>
<div class="form-group string optional nutritionist_profile_last_name"><label class="form-control-label string optional" for="nutritionist_profile_last_name">Last name</label><input class="form-control string optional" type="text" name="nutritionist_profile[last_name]" id="nutritionist_profile_last_name" /></div>
<div class="form-group string optional nutritionist_profile_work"><label class="form-control-label string optional" for="nutritionist_profile_work">Work</label><input class="form-control string optional" type="text" name="nutritionist_profile[work]" id="nutritionist_profile_work" /></div>
<div class="form-group integer optional nutritionist_profile_experience_years"><label class="form-control-label integer optional" for="nutritionist_profile_experience_years">Experience years</label><input class="form-control numeric integer optional" type="number" step="1" name="nutritionist_profile[experience_years]" id="nutritionist_profile_experience_years" /></div>
<div class="form-group string optional nutritionist_profile_how_heard"><label class="form-control-label string optional" for="nutritionist_profile_how_heard">How heard</label><input class="form-control string optional" type="text" name="nutritionist_profile[how_heard]" id="nutritionist_profile_how_heard" /></div>
<div class="form-group date optional nutritionist_profile_birthday"><label class="form-control-label date optional" for="nutritionist_profile_birthday_3i">Birthday</label><div class="d-flex flex-row justify-content-between align-items-center"><select id="nutritionist_profile_birthday_3i" name="nutritionist_profile[birthday(3i)]" class="form-control mx-1 date optional">

感谢任何帮助!

3 个答案:

答案 0 :(得分:0)

该表单似乎正在生成尝试使用create中未定义的UserProfilesController操作的请求。

我假设您想使用update来代替调试,为什么这样,您可以从浏览器(特别是“网络”标签)检查开发工具,并查看实际发出的请求是什么,为什么

如果您无法找到导致此问题的原因,请随时共享网络标签信息和来自stacktrace的更多详细信息...

编辑:看到您更新的html表单。 您的问题在simple_form_for之内,将其更改为(如其他人所述):

= simple_form_for @profile do |f|
...
# or setup the method/action explicitly (see the gem doc https://github.com/plataformatec/simple_form) 

答案 1 :(得分:0)

由于您实例化了@profile变量而不是profile变量:

def edit
  @profile = current_user.profile
end

怎么样:

= simple_form_for @profile do |f|

代替:

= simple_form_for(profile, url: user_profiles_path, action: 'update') do |f|

哦,我也看到你在做

= render 'form_for_client', profile: @profile

我不确定是否有必要将@profile作为局部变量传递给局部变量(在视图上下文中可能已经可用),但是如果有必要,我相信正确的语法会是:

= render 'form_for_client', locals: {profile: @profile}

在这种情况下,您可能会做:

= simple_form_for profile do |f|

...因为在您的视图上下文中,您现在将拥有profile变量(以本地方式传递),而不是@profile变量(在控制器中实例化) 。但是,再次声明,如果profile变量已经可用,则根本不需要传递@profile变量(您必须弄弄它才能看到-很久以前,我把所有内容都抽象了,这样就不必再弄乱了。

我不记得了,但是您可能还需要显式使用render partial语法:

= render partial: 'form_for_client', locals: {profile: @profile}

在可能的情况下,我个人更喜欢使用符号而不是字符串作为部分名称:

= render partial: :form_for_client, locals: {profile: @profile}

(根据评论)为什么还要使用resource:而不是resources:?另外,您需要定义resources: nutritionist_profilesresources: administrator_profiles。错误正是在告诉您。

顺便说一句,您收到“未定义方法'nutritionist_profiles_path”错误的原因是,您的:form_for_nutritionist看起来像是:

= simple_form_for profile do |f|

......其中,profileNutritionist的实例,给出以下逻辑:

- if current_user.instance_of?(Client)
  = render 'form_for_client', profile: @profile
- elsif current_user.instance_of?(Nutritionist)
  = render 'form_for_nutritionist', profile: @profile
- else
  = render 'form_for_administrator', profile: @profile

...并且simple_form_for使用class中的profile确定在这种情况下解析为nutritionist_profiles_path的路径。

答案 2 :(得分:0)

因为有before_action :load_profile 你不需要 @profile = current_user.profileedit中的update

还有

= simple_form_for @profile做| f |

替换为

 = simple_form_for(profile, url: user_profiles_path, action: 'update') do |f|

并在edit视图中替换

= render 'form_for_client', profile: @profile
= render 'form_for_nutritionist', profile: @profile
= render 'form_for_administrator', profile: @profile

使用

= render partial: "form_for_client", locals: { profile: @profile }
= render partial: "form_for_nutritionist", locals: { profile: @profile }
= render partial: "form_for_administrator", locals: { profile: @profile }

并替换

def profile_params
    params.require(:profile).permit(:name, :description, :first_name, :last_name, :nickname,
                                    :how_heard, :birthday, :experience_years)
  end

使用

def profile_params
params.require("#{current_user.type.downcase}_profile").permit(:name, :description, :first_name, :last_name, :nickname,
                                :how_heard, :birthday, :experience_years)

结束