Используйте вложенные атрибуты Ruby API и форму реакции - PullRequest
1 голос
/ 25 апреля 2020

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

задняя часть следующая * модель коктейля

class Cocktail < ApplicationRecord
  has_many :proportions
  has_many :ingredients, through: :proportions
  accepts_nested_attributes_for :proportions
end

модель компонентов

class Ingredient < ApplicationRecord
  has_many :proportions
  has_many :cocktails, through: :proportions
end

пропорционная модель

class Proportion < ApplicationRecord
  belongs_to :cocktail
  belongs_to :ingredient
  accepts_nested_attributes_for :ingredient
end

Метод создания контроллера коктейлей

  def create
   cocktail = Cocktail.new(cocktail_params)

   if cocktail
    cocktail.save
    render json: cocktail
   else
    redner json: {error: "cocktail not valid "}
   end

  end

  private 

  def cocktail_params
    params.require(:cocktail).permit(:name, :description, :instructions, :source)
  end

Пока я могу создать коктейль ... Я не уверен, как теперь можно интегрировать ингредиенты и добавьте это в бэкэнд.

отреагируйте похожим на это

<code>    import React, { useState, Fragment } from "react";



const FormCocktails = () => {

  const [inputFields, setInputFields] = useState([
    { name: '', description: '', instructions: "", source: ""}
  ]);


  ///here were we get the info we need to submit 
  const handleSubmit = e => {
    e.preventDefault();
    debugger
    const confObj = {
      method: "POST",
      headers: {
          "Content-Type": "application/json",
          "Accept": "application/json"
      },
      body: JSON.stringify({
          name: inputFields[0].name,
          description: inputFields[0].description,
          instructions: inputFields[0].instructions,
          source: inputFields[0].source
      })
    }

  fetch("http://localhost:3000//api/v1/cocktails", confObj)
      .then(response => response.json())
      .then(obj => console.log(obj))
      .catch(error => console.log(error))


}




  const handleInputChange = (index, event) => {

    const values = [...inputFields];
    if (event.target.name === "name") {
      values[index].name = event.target.value;
    } else if(event.target.name ==="description") {
      values[index].description = event.target.value;
    }else if(event.target.name ==="instructions") {
      values[index].instructions = event.target.value;
    }else{
      values[index].source = event.target.value;
    }


    setInputFields(values);
  };


  const handleAddFields = () => {
    const values = [...inputFields];
    inputFields.push({ instructions: "" });
    setInputFields(values);
  };

  const handleRemoveFields = index => {    

    const values = [...inputFields];
    values.splice(index, 1);
    setInputFields(values);
  };





////    { name: '', description: '', instructions: "", source: ""}
  return (
    <>
      <h1>New Cocktails</h1>
      <form onSubmit={handleSubmit}>
        <div className="form-row">
          {inputFields.map((inputField, index) => (
            <Fragment key={`${inputField}~${index}`}>
              <div className="form-group col-sm-6">
                <label htmlFor="name">Cocktail Name</label>
                <input
                  type="text"
                  className="form-control"
                  id="name"
                  name="name"
                  value={inputField.name}
                  onChange={event => handleInputChange(index, event)}
                />
              </div>
              <div className="form-group col-sm-4">
                <label htmlFor="description">Cocktail description</label>
                <input
                  type="text"
                  className="form-control"
                  id="description"
                  name="description"
                  value={inputField.description}
                  onChange={event => handleInputChange(index, event)}
                />
              </div>
              <div className="form-group col-sm-4">
                <label htmlFor="instructions">Cocktail instructions</label>
                <input
                  type="text"
                  className="form-control"
                  id="instructions"
                  name="instructions"
                  value={inputField.instructions}
                  onChange={event => handleInputChange(index, event)}
                />
              </div>
              <div className="form-group col-sm-4">
                <label htmlFor="source">Cocktail source</label>
                <input
                  type="text"
                  className="form-control"
                  id="source"
                  name="source"
                  value={inputField.source}
                  onChange={event => handleInputChange(index, event)}
                />
              </div>




              <div className="form-group col-sm-2">
                <button
                  className="btn btn-link"
                  type="button"
                  onClick={() => handleRemoveFields(index)}
                >
                  -
                </button>
                <button
                  className="btn btn-link"
                  type="button"
                  onClick={() => handleAddFields()}
                >
                  +
                </button>
              </div>
            </Fragment>
          ))}
        </div>
        <div className="submit-button">
          <button
            className="btn btn-primary mr-2"
            type="submit"
            onSubmit={(e) =>handleSubmit(e)}
          >
            Save
          </button>

        </div>
        <br/>
{/* <pre>
 {JSON.stringify(inputFields, null, 2)}
* /} )} экспорт по умолчанию FormCocktails;
...