Moving devise model to React.rb public directory calls method missing - ruby-on-rails

I'm trying to use Devise with React.rb, so I thought I'll move my user model to the public directory to be able to edit it through React, however I get this error:
ActionView::Template::Error(User.devise(database_authenticatable,registerable,recoverable,rememberable,trackable,validatable) (called class method missing)):
1: <%= react_component #component_name, #render_params, { prerender: !params[:no_prerender] } %>

You probably have some devise specific macros in your user model.
for example if you user model looks like this:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# etc...
end
then you will need to insure the devise call only runs on the server like this:
class User < ActiveRecord::Base
unless RUBY_ENGINE=='opal'
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
# etc...
end
Reactive-Record stubs and proxies all the standard active-record macros like scope, and belongs_to on the client. However it doesn't know what the devise method means, so wrapping it in unless RUBY_ENGINE=='opal will prevent this from being called on the client.
FYI I added an issue https://github.com/catprintlabs/reactive-record/issues/17 to reactive-record to cover this...

Related

attr_accessor does not work on associated objects that aren't saved

I haven't been able to find an explanation as to why attr_accessor works here:
fb_profile = FbProfile.where(identifier: params[:identifier]).first_or_initialize
fb_profile.signed_request = "randomstring"
logger.info(fb_profile.signed_request) # outputs "randomstring"
but not here:
current_admin.fb_profile = FbProfile.where(identifier: params[:identifier]).first_or_initialize
current_admin.fb_profile.signed_request = "randomstring"
logger.info(current_admin.fb_profile.signed_request) # outputs undefined
I can work like in the first example, but then I have to create the association later, which seems dirtier than just creating it from the get go. Is this common behavior?
Update1:
As some requested, here are the relevant parts of both models:
class Admin < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, :omniauthable
include DeviseTokenAuth::Concerns::User
has_one :fb_profile
end
class FbProfile < ApplicationRecord
belongs_to :admin
has_and_belongs_to_many :fb_pages
attr_accessor :signed_request
end
You're missing the relation between current_admin and fbprofile.
If you've a has_one relation I would write something like this :
current_admin.fb_profile ||= current_admin.build_fb_profile(identifier: params[:identifier])

"Validation Error: Password can't be blank" but no password field in form

I have a form to save information to a database for my website. Even though the form does not require a sign in, whenever I try to submit the form, I get an error "Validation failed: Password can't be blank". I'm not sure why this is happening as there is no password field in the form. Here is the code from the controller, the error is from the save line:
def create
#newinstructor = Instructor.new
#newinstructor_app = InstructorApp.where(first_name: params['instructor']['first_name']).where(last_name: params['instructor']['last_name'])
#newinstructor.first_name = params['instructor']['first_name']
#newinstructor.last_name = params['instructor']['last_name']
#newinstructor.story = params['instructor']['story']
#newinstructor.save!
Here is the instructor.rb:
class Instructor < ActiveRecord::Base
has_many :activities
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :activities
has_one :instructor_app
end
You should be able to fix, by following either of the following approaches:
Remove the :validatable option from your Instructor, devise option should now be:
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable
OR
add the following method to your Instructor
def password_required?
false
end
Let me know if that helps
It looks like you have Devise modules like :database_authenticatable in your instructor model. You cant see it but Devise expects there to be a password field by default. If there's no login for your instructor form then one option is to simply delete the devise modules. Devise is generally used for the User model if you have one, to authenticate when a user initially signs up and/or logs in

Rails Trying to create a profile after the user has been created

I'm trying to figure out how to create a new profile for the user that has just been created,
I'm using devise on the User model, and the User model has a one to one relationship with the UserProfile model.
Here's what my User Model looks like:
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
belongs_to :batch
has_one :user_profile
after_create :create_user_profile
def create_user_profile
self.user_profile.new(:name => 'username')
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
This generate the following error:
undefined method `new' for nil:NilClass
i've tried User.find(1).user_profile in rails c and that works so I'm pritty sure the relationship is setup correctly,
I'm probably being a big fat noob and trying to fetch self incorrectly.
plus can you also tell me how to access the params in a Model... is that even possible?
A has_one relationship will automatically add the :create_<relationship> and build_<relationship> methods. Checkout the rails guide.
You could try this:
after_create do
create_user_profile(:name => 'username')
end
Or more likely
after_create do
create_user_profile(:name => self.username)
end

unique after_sign_out paths with multiple models with Devise and rails

I have a rails 3.2 app with Devise 2.1
I have 2 models using devise (AdminUser and User)
Models:
class AdminUser < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
I have generated separate views for both models via the devise generator.
views/devise folder for AdminUser (implemented months earlier before new requirement)
views/users folder for User model
After signout, I want to redirect to specific actions that match the devise models. The code below works in application_controller.rb but it is applying to both models which I want to do without:
def after_sign_out_path_for(user)
user_landing_path
end
Signing out of either model redirects to the same landing page, but i would like to have a unique destination for both devise models.
How can I achieve this?
I figured out what seems to be a solution after looking at some examples here
http://eureka.ykyuen.info/2011/03/10/rails-redirect-previous-page-after-devise-sign-in/
def after_sign_out_path_for(resource_or_scope)
case resource_or_scope
when :user, User
user_landing_path
when :admin_user, AdminUser
admin_user_landing_path
else
super
end
end
Some things you could do:
case user.class
when AdminUser.class
do_admin_sign_out()
when User.class
do_user_sign_out()
else
no_idea_who_you_are()
end
or
if user.kind_of? AdminUser
do_admin_thing()
else
do_user_thing()
end
alternatively, you could add an admin? check to both models, and check that, ie:
if user.admin?
do_admin_thing()
...
I would probably do the later, as this might come up else where, but these are among your options.

Devise find_for_authentication not firing with multiple authentication keys

I have two devise models: User and Member
As such, I'm specifying authentication keys on the models themselves instead of in the Devise initializer.
Member.rb
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable, :authentication_keys => [:email, :subdomain]
I also override
def self.find_for_authentication(conditions={})
debugger
conditions[:account_id] = Account.find_by_subdomain(conditions.delete(:subdomain)).id
super(conditions)
end
Unfortunately, when authentication_keys has multiple keys, my find_for_authentication method doesn't appear to be firing. Works fine when I specify just one key. Any thoughts?
subdomain should have been a request_key since it's part of the request.
request_keys => [:subdomain]

Resources