我的Rails按钮未更新数据库

时间:2019-06-26 14:13:27

标签: ruby-on-rails

我创建了一个按钮,用户可以在其中输入内容,然后按下该按钮以更新数据库(put请求),可以在show.html.erb中看到此信息:

<% provide(:title, @user.name) %>
<div class="row">
  <aside class="col-md-4">
    <section class="user_info">
      <h1>
        <%= gravatar_for @user %>
        <%= @user.name %>
        <br>
        <%= @user.email %>
        <% if @errors  %>
          <p>THE FORM COULD NOT BE SAVED </p>
          <ul id='errors'>
          <% @errors.each do |error| %>
            <li><%= error %></li>
          <% end %>
          </ul>
        <% end %>
        <br>
        <% if is_admin? %>
          <% if !@user.admin %>
            <div class="row">
              <div class="col-md-6 col-md-offset-3">
                <%= form_for(@user) do |f| %>

                  <%= f.label :wistia_project_id %>
                  <%= f.text_field :wistia_project_id, class: 'form-control' %>

                  <%= f.submit "Save", :action => "set_wistia_project_ID", :method => :patch, :form_class => "form-control" %>
                <% end %>
              </div>
            </div>        
          <% end %>
        <% end %>
      </h1>
    </section>
  </aside>
</div>

该函数位于user_controller.rb中:

  # Sets wistia_project_ID.
  def set_wistia_project_ID
    @user = User.find(params[:id])
    @user.set_project_id
    unless @user.valid?
      @errors = @user.errors.full_messages
      render :show
    end
  end

该函数调用另一个函数,只是为了更清楚地分离事物。此其他函数位于user.rb中:

  # Sets the wistia_project_ID.
  def set_project_id!(val)
    self.wistia_project_ID = val # self is necessary here
    save # or self.save, but the self is unnecessary here
  end

我的routes.rb

.
.
.
  resources :users do
    member do
      patch 'set_wistia_project_ID'
    end
  end

我的问题是,当您按下按钮时,它说:Completed 500 Internal Server Error in 26ms (ActiveRecord: 0.7ms)

NoMethodError (undefined method `set_project_id' for #<User:0x000055b1a0914ab8>
2019-06-26T14:46:34.940086+00:00 app[web.1]: Did you mean?  wistia_project_id):

2 个答案:

答案 0 :(得分:3)

Zavitoski正确了。但是,我建议您所做的许多事情从根本上来说都是错误的。鉴于您尚处于起步阶段,我希望您不要介意我指出几点。

首先,要挑剔,是的,您创建了一个按钮。但是,它不是“用户可以在字段中输入内容然后按此按钮来更新数据库”的按钮。您在 form 上创建了一个按钮。然后您在该表单上创建了一个 field 。用户可以在现场输入内容。然后单击该按钮将提交包含该字段信息的表单。

现在,您在该表格上做了:

<%= form_for(@user) do |f| %>

  <%= f.label :wistia_project_id %>
  <%= f.text_field :wistia_project_id, class: 'form-control' %>

  <%= f.submit "Save", :action => "set_wistia_project_ID", :method => :patch, :form_class => "form-control" %>
<% end %>

有一些问题:

:action => "set_wistia_project_ID"

首先,set_wisteria_project_ID不是一个非常红宝石的动作名称。 set_wistia_project_id更像它。另外,您正在使用旧格式的键值格式。并且,您可以使用符号而不是字符串作为操作名称,从而使代码更漂亮。也许是这样的:

<%= f.submit "Save", action: :set_wistia_project_id, method: :patch, form_class: "form-control" %>

但是,这也是一个错误。因为您不需要执行set_wistia_project_id操作。 (这是actionmethod,而不是function。)您已经执行了update操作。如果form_for@user的实例,那么User足够聪明,可以执行此操作。因此,实际上,您应该这样做:

<%= form_for @user do |f| %>

  <%= f.label :wistia_project_id %>
  <%= f.text_field :wistia_project_id, class: 'form-control' %>

  <%= f.submit "Save", form_class: "form-control" %>

<% end %>

我不确定form_class是什么,但我相信它是正确的。

现在,在您的UsersController中,只需执行以下操作:

class UsersController < ApplicationController 

  def update
    @user = User.find(params[:id])
    if user.update(user_params)
      # do something successful
    else
      # do something unsuccessful
    end
  end

private

  def user_params
    # NOTE: You'll probably want to permit other stuff here, too.
    params.require(:user).permit(:wistia_project_id)
  end

end

摆脱这个:

class User < ApplicationRecord

  # Sets the wistia_project_ID.
  def set_project_id!(val)
    self.wistia_project_ID = val # self is necessary here
    save # or self.save, but the self is unnecessary here
  end

end

因为您只是在复制update方法。并且,您可能希望该属性为wistia_project_id,而不是wistia_project_ID。 (同样,您永远不会将_ID作为rails核心的后缀,并且您可能会很习惯。)而且,如果您确定关联设置正确,ActiveRecord应该确保wistia_project_id实际上是有效值。

然后像这样写您的routes.rb

resources :users

因为您不需要所有set_wistia_project_id业务。

答案 1 :(得分:2)

似乎您没有使用定义的名称来调用函数,也没有传递所需的参数(project_id)。

def set_wistia_project_ID
    @user = User.find(params[:id])
    @user.set_project_id!(params[:wistia_project_id])
    unless @user.valid?
      @errors = @user.errors.full_messages
      render :show
    end
  end

这应该使用您创建的函数并从表单中传递参数。