Commit eeede45

mo khan <mo@mokhan.ca>
2017-03-18 04:20:02
use gon to validation usernames on the client side.
1 parent cc8d233
Changed files (6)
app
assets
javascripts
lib
views
registrations
controllers
views
layouts
registrations
spec
app/assets/javascripts/lib/behaviours/autovue.js.coffee
@@ -2,9 +2,12 @@ class Stronglifters.Autovue extends Stronglifters.Behaviour
   @on "turbolinks:load"
 
   execute: ->
-    data = gon? ? gon : {}
     for element in $("[data-autovue]")
       window.views ?= []
       window.views.push new Vue
         el: element
-        data: data
+        data: @data()
+
+  data: ->
+    return gon if gon?
+    {}
app/assets/javascripts/views/registrations/new.js.coffee
@@ -1,12 +1,14 @@
 Vue.component "registration",
+  props: ['usernames']
   data: () ->
     terms_and_conditions: ''
     email: ''
     password: ''
     username: ''
+
   computed:
     validation: ->
-      username: @username.length > 0
+      username: @username.length > 0 && @usernameAvailable()
       email: @email.length > 0
       password: @password.length > 0
       terms_and_conditions: @terms_and_conditions
@@ -15,3 +17,7 @@ Vue.component "registration",
       validation = @validation
       Object.keys(validation).every (key) =>
         validation[key]
+
+  methods:
+    usernameAvailable: ->
+      !@usernames.includes(@username)
app/controllers/registrations_controller.rb
@@ -3,6 +3,7 @@ class RegistrationsController < PublicController
 
   def new
     @user = User.new
+    gon.usernames = User.pluck(:username).sort
   end
 
   def create
app/views/layouts/public.html.erb
@@ -19,6 +19,7 @@
     </header>
     <%= render partial: 'flash' %>
     <%= yield %>
+    <%= include_gon %>
     <script type="text/javascript" charset="utf-8">
       <%= content_for :javascript %>
     </script>
app/views/registrations/new.html.erb
@@ -1,7 +1,7 @@
 <div class="container" data-autovue="registration-view">
   <div class="columns">
     <div class="column is-6 is-offset-3">
-      <registration inline-template>
+      <registration v-bind:usernames="usernames" inline-template>
       <%= form_for @user, url: registrations_path do |f| %>
         <p class="control has-icon has-icon-right">
           <%= f.text_field :username, placeholder: t('.username'), class: 'input is-large', required: 'required', "v-model.trim": "username", "v-bind:class": "{ 'is-danger': !validation.username, 'is-success': validation.username }" %>
spec/controllers/registrations_controller_spec.rb
@@ -2,10 +2,18 @@ require "rails_helper"
 
 describe RegistrationsController do
   describe "#new" do
+    let(:gon) { RequestStore.store[:gon].gon }
+
     it "loads a new user" do
       get :new
       expect(assigns(:user)).to be_new_record
     end
+
+    it 'loads the used usernames' do
+      user = create(:user)
+      get :new
+      expect(gon).to match_array([["usernames", [user.username]]])
+    end
   end
 
   describe "#create" do