Завершено 422 Unprocessable_entity при отправке формы в Rails Api из приложения Vuejs - PullRequest
0 голосов
/ 21 октября 2019

Я создаю приложение, используя Rails 6 Api в качестве бэкэнда и Vue в качестве отдельного веб-приложения.

Я только что создал свою регистрационную форму, однако при отправке я получаю Completed 422 Unprocessable Entity ошибку. Я не могу за свою жизнь понять, куда я иду не так.

Как работает форма:

Я создаю пользователя и Учетную запись в одной форме, используя учетную запись accepts_nested_attributes_for:. форма подключается к контроллеру регистрации, как показано ниже:

class SignupController < ApplicationController

  def create
    user = User.new(user_params)
    if user.save
      payload = { user_id: user.id }
      session = JWTSessions::Session.new(payload: payload, refresh_by_access_allowed: true)
      tokens = session.login

      response.set_cookie(JWTSessions.access_cookie,
                          value: tokens[:access],
                          httponly: true,
                          secure: Rails.env.production?)
      render json: { csrf: tokens[:csrf] }

      set_trial

    else
      render json: { error: user.errors.full_messages.join(' ') }, status: :unprocessable_entity
    end
  end

  protected

  private

    def user_params
      params.permit(:f_name, :l_name, :email, :password, :password_confirmation, account_attributes: [:company_name])
    end 

    def set_trial
      account = user.account
      account.update!(trial_start: DateTime.now, trial_end: 7.days.from.now, is_active: true)
    end

end

Когда я отправляю форму, см. ниже) Я получаю эту ошибку на моем сервере rails.

Started POST "/signup" for ::1 at 2019-10-20 22:10:09 -0600
   (0.5ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Processing by SignupController#create as HTML
  Parameters: {"company_name"=>"tauren group", "f_name"=>"Sxxx", "l_name"=>"Wxxx", "email"=>"xxx@xxx.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "signup"=>{"company_name"=>"tauren group", "f_name"=>"Sxxx", "l_name"=>"Wxxx", "email"=>"xxx@xxx.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}}
Unpermitted parameters: :company_name, :signup
   (0.2ms)  BEGIN
  ↳ app/controllers/signup_controller.rb:5:in `create'
   (0.2ms)  ROLLBACK
  ↳ app/controllers/signup_controller.rb:5:in `create'
Completed 422 Unprocessable Entity in 290ms (Views: 0.3ms | ActiveRecord: 5.9ms | Allocations: 13334)

Чего я не понимаю, так это того, как регистрация передается в параметре, и почему company_name не разрешено.

Вот мой компонент Vue:

<template>
  <div class="flex h-screen items-center justify-center -mt-20">
    <div class="flex flex-wrap w-full justify-center">
      <div class="w-full text-center mb-4 text-xs lg:text-sm headerFont tracking-wide text-link-blue">
        Start your free 7 day trial. No credit card required. No obligation to continue.
      </div>
      <div class="w-full lg:w-7/12 bg-gray-200 p-6 rounded-lg shadow-md">
       <form @submit.prevent="signup">
        <div class="w-full mb-4">
            <label for="user_account_attributes_company_name" class="label headerFont">Company Name</label>
            <input type="text" v-model="company_name" name="user[account_attributes][company_name]" class="form-input w-full block" id="user_account_attributes_company_name" />
          </div>
          <div class="flex flex-wrap w-full mb-4">
            <div class="w-full lg:w-1/2">
              <label for="user_f_name" class="label headerFont">First Name</label>
              <input type="text" v-model="f_name" name="user[f_name]" id="user_f_name" class="form-input w-full lg:w-11/12 block" />
            </div>
            <div class="w-full lg:w-1/2">
              <label for="user_l_name" class="label headerFont">First Name</label>
              <input type="text" v-model="l_name" name="user[l_name]" id="user_l_name" class="form-input w-full block" />
            </div>
          </div>
          <div class="w-full mb-4">
            <label for="user_email" class="label headerFont">Email Address</label>
            <input type="email" v-model="email" name="user[email]" id="user_email" class="form-input w-full block" />
          </div>
          <div class="flex flex-wrap w-full mb-4">
            <div class="w-full lg:w-1/2">
              <label for="user_password" class="label headerFont">Password</label>
              <input type="password" v-model="password" name="user[password]" id="user_password" class="form-input w-full lg:w-11/12 block" />
            </div>
            <div class="w-full lg:w-1/2">
              <label for="user_password_confirmation" class="label headerFont">Confirm Password</label>
              <input type="password" v-model="password_confirmation" name="user[password_confirmation]" id="user_password_confirmation" class="form-input w-full block" />
            </div>
          </div>
          <div class="flex w-full justify-center">
            <button type="submit" class="p-3 bg-green-600 rounded headerFont text-white hover:bg-green-400">
              Start My Trial
            </button>
          </div>
        </form>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Signup',
  props:{
    user: Object
  },
  data () {
    return {
      company_name: '',
      f_name: '',
      l_name: '',
      email: '',
      password: '',
      password_confirmation: '',
      error: ''
    }
  },
  created () {
    this.checkedSignedIn()
  },
  updated () {
    this.checkedSignedIn()
  },
  methods: {
    signup () {
      this.$http.plain.post('/signup', { company_name: this.company_name, f_name: this.f_name, l_name: this.l_name, email: this.email, password: this.password, password_confirmation: this.password_confirmation })
        .then(response => this.signupSuccessful(response))
        .catch(error => this.signupFailed(error))
    },
    signupSuccessful (response) {
      if (!response.data.csrf) {
        this.signupFailed(response)
        return
      }
      localStorage.csrf = response.data.scrf
      localStorage.signedIn = true
      this.error = ''
      this.$router.replace('/dashboard')
    },
    signupFailed (error) {
      this.error = (error.response && error.response.data && error.response.data.error) || 'Something Went Wrong'
      delete localStorage.csrf
      delete localStorage.signedIn
    },
    checkedSignedIn () {
      if (localStorage.signedIn) {
        this.$router.replace('/dashboard')
      }
    }
  }
}
</script>

И просто для хороших мер вот моя конфигурация маршрутов:

  namespace :api do
    namespace :v1 do

    end
  end

  post   'refresh', controller: :refresh, action: :create
  post   'signin',  controller: :signin,  action: :create
  post   'signup',  controller: :signup,  action: :create
  delete 'signin',  controller: :signin,  action: :destroy

Любая помощь здесь будет очень цениться! Я новичок в Vue и не имел большого опыта в создании API! спасибо заранее и, пожалуйста, дайте мне знать, если потребуется дополнительная информация!

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