You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi Darcy,
Thanks for the handy gem. I've got one question I couldn't find an easy solution for, maybe you can help me out with this.
I have two separate applications (one for regular users, another administration) with a single user base, the admin app acting as a web service for the user app (the API client). I need to display validation errors on login/registration forms in the user app. Since the user app is not backed by a DB, things become a little unwieldy on the client side since I don't get any of the ActiveModel convenience stuff out of the box when using RP clients instead of ActiveRecord models. Here's what I had to do to get the errors displayed properly.
I defined base classes for clients and the hashes they encapsulate (they are later used to trick form builder into binding input fields to attributes). The encapsulated 'model' has to have a model_name method and an ActiveModel error hash, otherwise simple_form_for will die with exceptions I've spent about 3 hours debugging :(
module Api
class Base < RocketPants::Client
version 1
base_uri Rails.application.config.api.base_uri
attr_accessor :auth_token
def base_request_options
session[:user] ? { headers: { 'X-AUTH' => session[:user][:auth_token] } } : {}
end
end
class ModelBase < APISmith::Smash
property :id
property :errors
def self.model_name
ActiveModel::Name.new(self)
end
def to_key
id
end
def populate_errors_from(error_hash)
self.errors = ActiveModel::Errors.new(self)
error_hash.each do |attr, msgs|
msgs.each { |msg| self.errors.add(attr, msg) }
end
end
end
end
Now, a client for the User model:
class Api::UserClient < Api::Base
class User < Api::ModelBase
property :first_name
property :last_name
property :email
property :password
property :password_confirmation
property :provider_id
end
attr_reader :user
def initialize(*args)
@user = User.new(*args)
super(*args)
end
def find(id)
get "/user", extra_query: { id: id }
end
def save
post "/users", extra_query: { user: @user }
end
end
The corresponding controller on the client application side is below. It rescues the invalid record exception raised by the client base code, populates the error hash and re-renders the action with the form.
class UsersController < ApplicationController
skip_before_filter :authenticate, only: [:new, :create]
def create
@user_client = Api::UserClient.new(params[:user])
respond_to do |format|
begin
@user_client.save
rescue RocketPants::InvalidResource => e
format.html do
@user = @user_client.user
@user.populate_errors_from(e.errors)
render action: :new
end
else
format.html { redirect_to root_path, notice: t("signed_up_but_not_approved") }
end
end
end
end
This works, but feels way too convoluted for a simple scenario like this. I feel there should be an easier way to do this.
I guess this post is a little too long, but anyway I'd be grateful if you could read through this and point me in the right direction here. I hope I've explained everything clear enough.
Thanks.
The text was updated successfully, but these errors were encountered:
Hi Darcy,
Thanks for the handy gem. I've got one question I couldn't find an easy solution for, maybe you can help me out with this.
I have two separate applications (one for regular users, another administration) with a single user base, the admin app acting as a web service for the user app (the API client). I need to display validation errors on login/registration forms in the user app. Since the user app is not backed by a DB, things become a little unwieldy on the client side since I don't get any of the ActiveModel convenience stuff out of the box when using RP clients instead of ActiveRecord models. Here's what I had to do to get the errors displayed properly.
I defined base classes for clients and the hashes they encapsulate (they are later used to trick form builder into binding input fields to attributes). The encapsulated 'model' has to have a model_name method and an ActiveModel error hash, otherwise
simple_form_for
will die with exceptions I've spent about 3 hours debugging :(Now, a client for the User model:
The corresponding controller on the client application side is below. It rescues the invalid record exception raised by the client base code, populates the error hash and re-renders the action with the form.
This works, but feels way too convoluted for a simple scenario like this. I feel there should be an easier way to do this.
I guess this post is a little too long, but anyway I'd be grateful if you could read through this and point me in the right direction here. I hope I've explained everything clear enough.
Thanks.
The text was updated successfully, but these errors were encountered: