Rails 5 API + Vue.js前端:用devise_invitable邀请用户的表单

时间:2017-11-17 10:01:56

标签: ruby-on-rails vue.js devise-invitable devise-token-auth

我正在和Vue.js一起写一份邀请函。邀请应POST到Rails 5 API。我正在使用devise_invitable进行邀请逻辑和电子邮件发送。但是,我遇到了拦截create方法的问题,因为我会向多个用户发送邀请,因此我想为参数中的每个用户执行User.invite!

我的 invite.vue 文件,其中包含要发布的表单:

<template>
  <b-row>
    <b-col>
      Invite {{form.length}} members

      <b-form @submit.prevent="submitStaffInvite" id='staffInvite'>
        <div v-for="(row, idx) in form">
          <b-row>
            <b-col cols="3">
              <b-form-group id="firstNameGroup" label="First name">
                <b-form-input id="firstNameInput" name="user[first_name][]" type="text" v-model="row.firstName" autofocus></b-form-input>
              </b-form-group>
            </b-col>
            <b-col cols="3">
              <b-form-group id="lastNameGroup" label="Last name">
                <b-form-input id="lastNameInput" name="user[last_name][]" type="text" v-model="row.lastName"></b-form-input>
              </b-form-group>
            </b-col>
            <b-col cols="3">
              <b-form-group id="emailGroup" label="Staff email">
                <b-form-input id="emailInput" name="user[email][]" type="text" v-model="row.email"></b-form-input>
              </b-form-group>
            </b-col>
            <b-col cols="3">
              <b-button @click='removeRow(idx)'>Remove invitation</b-button>
            </b-col>
          </b-row>
        </div>
        <br />
        <b-button-group>
          <b-button @click.prevent='addRow'>Add invitation</b-button>
        </b-button-group>
        <br />
        <b-button-group>
          <b-button type="submit" variant="primary">Submit</b-button>
        </b-button-group>

      </b-form>
    </b-col>
  </b-row>
</template>

<script>
  export default {
    data: () => {
      return {
        form: [
          {
            email: '',
            firstName: '',
            lastName: ''
          }
        ]
      }
    },
    methods: {
      addRow: function () {
        this.form.push({
          email: '',
          firstName: '',
          lastName: ''
        })
      },
      removeRow: function (idx) {
        this.form.splice(idx, 1)
      },
      submitStaffInvite: function () {
        this.$axios.post('http://localhost:3001/auth/invitation', this.form)
          .then((res) => {
            if (res.status === 200) {
              this.$notify({
                text: res.data.message,
                group: 'alerts',
                type: 'success'
              })
            }
          })
          .catch(function (error) {
            error.response.data.errors.forEach((err) => {
              this.$notify({
                text: err,
                group: 'alerts',
                type: 'warning'
              })
            })
          })
      }
    }
  }
</script>

我的 users / invitations_controller.rb

class Users::InvitationsController < Devise::InvitationsController
  before_action :configure_permitted_parameters

  def create
    # TODO
    # Send email to each user in the form.
  end

  def edit
    sign_out send("current_#{resource_name}") if send("#{resource_name}_signed_in?")
    set_minimum_password_length
    resource.invitation_token = params[:invitation_token]
    redirect_to "http://localhost:3001/auth/invitation/accept?invitation_token=#{params[:invitation_token]}"
  end

  def update
    super do |resource|
      if resource.errors.empty?
        render json: { status: "Invitation Accepted!" }, status: 200
      else
        render json: resource.errors, status: 401
      end
    end
  end

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:accept_invitation, keys: [:first_name, :last_name])
  end
end

我的 routes.rb

Rails.application.routes.draw do
  # Using devise_token_auth for the API
  mount_devise_token_auth_for 'User', at: 'auth',
                                      defaults: { format: :json },
                                      controllers: {
                                        invitations: 'users/invitations'
                                      }
  ...
end

我可以看到存在以下路线:

PUT      /auth/invitation(.:format)            devise/invitations#update
POST     /auth/invitation(.:format)            devise/invitations#create

我在这里可以看到的问题是,我希望路线看起来像这样:

PUT      /auth/invitation(.:format)            users/invitations#update
POST     /auth/invitation(.:format)            users/invitations#create

此行为可能是由devise_token_auth gem引起的,我不确定如何更正。

同样,当我提交此表单时,我希望能够拦截create方法,然后在表单中列出的所有用户上调用User.invite!。我尝试在byebug方法中添加binding.prycreate,但代码似乎没有执行,这意味着它被绕过了。

我看到的错误信息是:

Processing by Devise::InvitationsController#create as HTML
  Parameters: {"_json"=>[{"email"=>"asd@ad.com", "firstName"=>"Test", "lastName"=>"Last"}], "invitation"=>{"_json"=>[{"email"=>"asd@ad.com", "firstName"=>"Test", "lastName"=>"Last"}]}}
Completed 500 Internal Server Error in 0ms (ActiveRecord: 0.0ms)



ArgumentError (wrong number of arguments (given 1, expected 0)):

我不应该将表单数据传递给devise_invitable的create方法吗?非常感谢任何帮助。

提前致谢!

1 个答案:

答案 0 :(得分:0)

尝试将路线更改为

mount_devise_token_auth_for 'User', at: 'auth', skip: [:invitations]

devise_for :users, path: "auth", only: [:invitations],
controllers: { invitations: 'users/invitations' }

有关详细信息,请参阅this article