【问题标题】:Server side Rails model validation in a React formReact 表单中的服务器端 Rails 模型验证
【发布时间】:2020-11-26 04:29:15
【问题描述】:

我正在尝试使用 React 作为视图来验证 Rails 应用程序中服务器端的用户输入。基本上我像这样对 Rails API 进行 axios 调用:

const Script = props => {
  const [script, setScript] = useState({})
  const [scene, setScene] = useState({})
  const [loaded, setLoaded] = useState(false)

  useEffect(() => {
    const scriptID = props.match.params.id
    const url = `/api/v1/scripts/${scriptID}`

    axios.get(url)
    .then( resp => {
      setScript(resp.data)
      setLoaded(true)
    })
    .catch(resp => console.log(resp))

  }, [])

  const handleChange = (e) => {
    e.preventDefault()
    setScene(Object.assign({}, scene, {[e.target.name]: e.target.value}))
  }

  const handleSubmit = (e) => {
    e.preventDefault()

    const csrfToken = document.querySelector('[name=csrf-token]').content
    axios.defaults.headers.common['X-CSRF-TOKEN'] = csrfToken

    const script_id = script.data.id
    axios.post('/api/v1/scenes', {scene, script_id})
    .then(resp => {
      const included = [...script.included, resp.data.data]
      setScript({...script, included})
    })
    .catch(err => {
      console.log(err.response.data.error)
    })
    .finally(() => {
      setScene({name: '', description: ''})
    })

  }

所有数据都通过表单传递到反应组件中。

  return (
    <div className="wrapper">
      {
        loaded &&
          <Fragment>
            .
            .
            .
            <SceneForm
              handleChange={handleChange}
              handleSubmit={handleSubmit}
              attributes={script.data.attributes}
              scene={scene}
            />
          </Fragment>
      }
    </div>
  )

在此表单中,我有一个名称字段,并且 Rails 中的相应名称具有验证唯一性:true。如果我输入有效(唯一)名称,一切正常。

我尝试实施验证,但对结果不满意。 (它通常可以工作:我的 no_errors? 方法做了应该做的事情,我得到了 403 状态)这是控制器部分:

  def create
    scene = script.scenes.new(scene_params)
    if no_error?(scene)
      if scene.save
        render json: SceneSerializer.new(scene).serialized_json
      else
        render json: { error: scene.errors.messages }, status: 422
        # render json: { error: scene.errors.messages[:name] }, status: 423
      end
    else
      render json: { error: "name must be unique" }, status: 403
    end
  end

.
.
.

  private

  def no_error?(scene)
    Scene.where(name: scene.name, script_id: scene.script_id).empty?
  end

如果我输入现有名称,我会得到一个如下所示的 console.log:

screenshot

这是我的担忧:我对我的错误处理方法不满意。我不想将 403 消息记录到控制台(我确实想首先避免此消息)。 我的想法是采取“简单形式”的方法:将我的字段的边框设为红色并在字段下发布错误消息,没有任何控制台输出...... 附带说明:403 是正确的状态吗?我在考虑 422 但不确定...

提前感谢您的想法!

【问题讨论】:

    标签: ruby-on-rails reactjs validation error-handling


    【解决方案1】:

    403 是错误的状态码。您需要返回 422 (unprocessable entity)。 403 更多的是关于政策和您有权做什么。

    然后,当您处理 http 请求时,在浏览器控制台中打印请求和状态代码是一个标准。不想在这里解决您的问题。 如果它即将显示错误,如果状态代码响应为 422,您可以只使用一个函数来着色(或任何您想要的烟花)您的输入。

    【讨论】:

    • 谢谢!我知道怎么放烟花。我只是认为我的一般方法可能是错误的。如果我使用标准 Rails 表单(或简单表单),我显然有另一种方法来验证我的模型:如果需要名称但未输入,我会得到没有任何控制台输出的烟花。而且我不确定我的验证方法是否是“良好做法”
    猜你喜欢
    • 2014-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多