Кнопка My Rails не обновляет базу данных - PullRequest
0 голосов
/ 26 июня 2019

Я создал кнопку, в которой пользователи могут вводить данные в поле, а затем нажать кнопку, чтобы обновить базу данных (запрос 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 ]

3 голосов
/ 26 июня 2019

Завитоски понял все правильно. Я полагаю, однако, что вы делаете ряд вещей более фундаментально неправильно. Учитывая, что вы находитесь в начале пути, я надеюсь, вы не против, если я укажу несколько вещей.

Во-первых, чтобы быть придирчивым, да, вы создали кнопку. Но это не кнопка «где пользователи могут вводить данные в поле, а затем нажимать кнопку для обновления базы данных». Вы создали кнопку на форме . И вы создали поле в этой форме. Пользователь может вводить материал в поле. И при нажатии, кнопка отправляет форму, которая включает в себя информацию в поле.

Теперь в этой форме вы сделали:

<%= 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 действие. (Это action или method, а не 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 бизнес.

2 голосов
/ 26 июня 2019

Похоже, что вы не вызываете функцию по указанному вами имени и не передаете необходимый параметр (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

Для этого следует использовать созданную вами функцию и передать параметр из формы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...