React表单没有在Rails应用程序中向Postgres提交值

时间:2018-01-17 23:16:10

标签: ruby-on-rails reactjs

我有一个通过Webpacker安装了React的rails应用程序。我在现有表单中添加了几个动态字段,但我没有将值提交给数据库。非反应字段提交正常,并且没有错误。

根据所选的选项,我显示了不同的数字字段。我理解下面的反应部分:

<input type="text_field" id="roast_country" name="roast[country]" className="form-control" />

等同于rails:

  <div class="form-group">
    <%= form.label :country, class: 'control-label' %>
    <%= form.text_field :country, id: :roast_country, class: "form-control" %>
  </div>

这太简单了吗?我从根本上错过了一些东西吗?

应用/ JavaScript的/ BlendSelector / beans.jsx

import React from 'react'
import ReactDom from 'react-dom'
import BlendSelector from 'BlendSelector'

document.addEventListener('turbolinks:load', function () {
  var element = document.getElementById("blend-type-component");
  ReactDom.render(<BlendSelector />, element);
});

应用/ JavaScript的/包/ index.jsx

import React          from 'react'

import NoBlend        from './NoBlend';
import SingleOrigin   from './SingleOrigin';
import TwoBlend       from './TwoBlend';
import ThreeBlend     from './ThreeBlend';

class BlendSelector extends React.Component {
  constructor(props) {
    super(props);
    this.onBlendSelected = this.onBlendSelected.bind(this);
    this.state = { selectedBlend: null };
  }

  onBlendSelected(event) {
    this.setState({ selectedBlend: event.target.value });
  }

  render() {
    let BlendCustomComponent = NoBlend;
    if (this.state.selectedBlend == "Single Origin") {
      BlendCustomComponent = SingleOrigin;
    } else if (this.state.selectedBlend == "Two Country Blend") {
      BlendCustomComponent = TwoBlend;
    }  else if (this.state.selectedBlend == "Three Country Blend") {
      BlendCustomComponent = ThreeBlend;
    }
    return (
      <div>
        <div className="field">
          <label htmlFor="roast_beans">Beans</label>
          <select id="beans" onChange={this.onBlendSelected} name="roast[beans]">
            <option value="">Select a blend type</option>
            <option value="Single Origin">Single Origin</option>
            <option value="Two Country Blend">Two Country Blend</option>
            <option value="Three Country Blend">Three Country Blend</option>
          </select>
        </div>
        <BlendCustomComponent />
      </div>
    );
  }
}
export default BlendSelector

应用/ JavaScript的/ BlendSelector / SingleOrigin.jsx

import React from 'react'

class SingleOrigin extends React.Component {
  render() {
    return (
      <div>
        <div className="form-group">
          <label htmlFor="country">Country</label>
          <input type="text_field" id="roast_country" name="roast[country]" className="form-control" />
        </div>
        <div className="form-group">
          <label htmlFor="region">Region</label>
          <input type="text_field" id="roast_region" name="roast[region]" className="form-control" />
        </div>
      </div>
    );
  }
}
export default SingleOrigin

roasts_controller.rb

def roast_params
  params.require(:roast).permit(:roaster, :name, :country, :region, :country2, :region2, :country3, :region3, :bestfor, :beans, :roast, :tastingnotes, :notes, :slug)
end

我通过调用<div id="blend-type-component"></div>在Rails表单中使用该组件:

应用/视图/烤肉/ _form.html.erb

<%= form_with(model: roast, local: true) do |form| %>
  <% if roast.errors.any? %>
    <div id="error_explanation">
      <div class="alert alert-danger" role="alert">
      <h2><%= pluralize(roast.errors.count, "error") %> prohibited this roast from being saved:</h2>

      <ul>
      <% roast.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  </div>
  <% end %>

<form>


  <div class="field form-group">
    <%= form.label :roaster, class: 'control-label' %>
    <%= form.text_field :roaster, id: :roast_roaster, class: "form-control" %>
  </div>

  <div class="form-group">
    <%= form.label :name, class: 'control-label' %>
    <%= form.text_field :name, id: :roast_name, class: "form-control" %>
  </div>

<div id="blend-type-component"></div>

  <div class="form-group">
    <%= form.label :bestfor, "Best for", class: 'control-label' %><br />
    <%= form.select :bestfor, [ 'Espresso','Filter' ], :prompt => 'Select One', id: :roast_bestfor, class: "form-control" %>
  </div>

  <div class="form-group">
    <%= form.label :roast, class: 'control-label' %><br />
    <%= form.select :roast, [ 'Light','Medium','Dark' ], :prompt => 'Select One', id: :roast_roast, class: "form-control" %>
  </div>

  <div class="form-group">
    <%= form.label :tastingnotes, "Tasting Notes (separate with commas, e.g chocolate, citrus)", class: 'control-label' %><br  />
    <%= form.text_area :tastingnotes, id: :roast_tastingnotes, class: "form-control" %>
  </div>
<br />

  <div class="actions">
    <%= form.submit class: "btn btn-primary" %>
  </div>
<% end %>

</form>

1 个答案:

答案 0 :(得分:0)

我认为主要问题是您的SingleOrigin组件实际上没有进行任何提交。这是带有handleSubmit事件的组件的修改版本:

class SingleOrigin extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: ''
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    // handle multiple inputs
    const target = event.target;
    const value = target.value;
    const name = target.name;

    this.setState({
      [name]: value // set the key as the name of the input element
    });

    console.log(this.state);
  }

  handleSubmit(event) {
    // Modify this to handle your actual submits to Postgres.
    alert('The following was submitted: ' + this.state.country + ', ' + this.state.region);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <div className="form-group">
          <label htmlFor="country">Country</label>
          {/* I modified your input names to just the keys so you can use the ES6 computed property name syntax, when you do your handle submit code, send it to the proper variables. */}
          <input type="text_field" id="roast_country" name="country" className="form-control" onChange={this.handleChange} />
        </div>
        <div className="form-group">
          <label htmlFor="region">Region</label>
          <input type="text_field" id="roast_region" name="region" className="form-control" onChange={this.handleChange}/>
        </div>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

此外,您希望使用form元素充分利用React的状态功能。要阅读有关表单的更多信息,请参阅this doc article。您还需要修改其他组件以处理表单数据的提交。