optimistically save session in authlogic - ruby-on-rails

I am trying to create similar functionality as this gem authlogix-rpx, which optimistically saves the session/user object even if some of the validated fields are missing.
http://github.com/tardate/authlogic_rpx/tree/master/lib/authlogic_rpx (line 167)
With this gem it's possible to create the record that does not meet validation criteria and later on call the registration_complete? method which return false if all the validations do not pass.
I am not sure how this save is taking place, in my gem (which is an add on to authlogic using oauth2) I have tried doing save(false), save_with_vaidation_false but nothign really works, the validations fail and the record get saved.
Any ideas?
Thanks

You should be able to run user.save(false) to save the user and then use user.errors.full_messages to access the validation error messages.
Or you could provide the :on parameter to your validations to restrict them to :create, :update or both (:save)
validates_presence_of :email, :on=>:update

Related

Rails - Validating a record without adding errors

Question is as above. I have a record that I need to validate before deciding which form to show. The record is created invalid, and we check its validity to see if the form the user is on is the initial registration form or a subsequent form.
My issue is when I call record.valid? the record gets various error messages added to it which are then incorrectly displayed on the registration form. It's not possible for me to simply clear the errors after validating as I need the errors present if the user enters invalid data.
Is there any way to call valid? or an equivalent that does not add errors to the instance?
Thanks in advance
You want to validates with a steps system ? I think you can look at with_options block.
example :
with_options condition do
# your validations or anything...
# validates :attribute
end
documentation :
https://apidock.com/rails/Object/with_options
With good conditions you will avoid adding errors on validations already "validated" and focus on the new ones.
I hope I understood your request correctly.
After calling valid? you can clear errors from object ie.
record.errors.clear

Rails - ping user without authenticating?

So I'm writing a Facebook clone for a school project using Rails and I need some way to keep track of which users are logged in. At the moment, I'm a bit time-pressed, so I decided just to update the User model every time they visit a page with a last_seen attribute.
Problem is, the user model requires revalidation to successfully update_attributes. So I'm wondering two things:
Is there a better way to do this that I'm missing?
If not (or if it would take too long) is there a way to bypass the validation?
to 1.: I cant give you an exact answer but I think itwould be better to deal with this problem using a javascript on the clientside with a timer that sends an ajax request all xxx secounds and an action that receives this requests and saves it in a seperate table associated with the User.
to 2.: Yes there are some ways to bypass validations The most pragmatic way is to bypass the :validate => false option when saving the object but then you can use update_attributes:
object.save(:validate => false)
So there is also the possibility to use conditional validations that are only used when a specific condition is complyed. There is a railscast about that => http://railscasts.com/episodes/41-conditional-validations .

Is there a way in Rails to say "run all the validates EXCEPT :password"?

I am using Devise for my authentication. If a hashed_password isn't set, Rails/Devise's validations will require a password to be set, as well as the password_confirmation.
When I invite new users, I obviously don't want to set their password, so when I create the invitation in my system, it fails because user.password is blank.
I can set a temporary hashed_password on the user, but when they enter their own password, the validation checks for :password and :password_confirmation will not happen because hashed_password is set, which is a real problem.
Is there any way to tell Rails that I want to run all the validations except for the ones associated with :password?
I know Rails has :if conditions, which might fix my problem, but Devise declares the :password validation on my behalf, so that essentially is hidden.
How can I get the desired result here?, hopefully in a way that is not a hack.
My current hypothetical solution that is somewhat messy: The only thing I can think of is to create a new Invitation model that is not the User model, and use the Invitation model for the form. When the invitation is submitted I can validate that Invitation and copy over all the values to the new User model. I can save that User without any validations at all.
That's the best solution I dreamed up.
It seems like my solution will be a lot more work than saying something simple like:
user.save(validations => {:except => :password})
EDIT: I have found one part of the solution, but I am still having problems. In our user model, we can override a Devise method to prevent the validation of the password for invitations with this bit of code:
#protected
def password_required?
!is_invited && super
end
The is_invited attribute is just a column I added to the users table/model.
However, there is one gotcha here. When a user accepts an invitation and they arrive to the form where they need to set their password/password_confirmation, valid? will always return true.
This one has me deeply perplexed. I don't see how requires_password? and valid? can be true at the same time. If it requires the password, it should do a validation check and cause the validations to fail.
I'm starting to hate Devise - or just the idea of using gems to build parts of your application in a blackbox. I think the real solution probably is to rip out Devise and just do it all from scratch. That way your app has total control of how all of this works :(
I recently started using this great devise add-on: devise_invitable
It's commonly used so users (or any model) can invite other users to join.
But I adapt it for manually (via an admin panel) invite new potential users to my app.
Hope this helps!

Set Authlogic validate_login_field to false on user update

We have a current database of users who can have any symbol in their username. We have started using authlogic for authentication. So, any current users updating any of their information fail validations because their login has unaccepted characters.
We want to prevent new users signing up from using symbols not accepted by authlogic, but those who have them already in their login to continue using them.
I know that I need to use something like this:
acts_as_authentic do |c|
c.validate_login_field = false
end
My questions is how do I set validate_login_field to false for already existing users but leave it to default value of true for new users signing up? Thanks.
I would suggest forgetting about that particular validation feature in Authlogic for your particular case (i.e. keep it as c.validate_login_field = false) and use validates_format_of setting a :with clause to a regex to ensure Authlogic valid user names and an :if clause to some proc or method private method which returns true if the validation should be done at all (using some application specific logic of your own design)
Or you can not to turn of validate_login_field and add :if option to validates_format_of_login_field_options
UPDATE:
Actually forget, it's a bad idea, because in that case you have to provide :if option for every possible validation.
Not only for validates_format_of_login_field_options, but for validates_length_of_login_field_options and validates_uniqueness_of_login_field_options

Authlogic run validations on login prior to create action

I need to run the built-in validations on the login field prior to actually creating the user record, is there a way to do this in Authlogic? The reason for is when a user types in a new login, AJAX is invoked to check and see that the login in unique, valid, etc. Once that is done, the user can enter his email to claim the login, it's a 2 step process.
The User model uses ActiveRecord validations, so this isn't specific to Authlogic. If you want to run the validations on a model you can call user.valid?. This will return true or false depending on if the entire model is valid. However it also fills up the user.errors object so you can then check if a given attribute is valid.
Here is some code that uses RJS to do the AJAX. But you can use anything and organize it however you want.
user = User.new(params[:user])
user.valid? # we aren't interested in the output of this.
error = user.errors.on(:login)
if error
page.insert_html :before, "user_login", content_tag(:span, error, :class => "error_message")
end
You may be interested in my Mastering Rails Forms screencast series where I cover this topic in the 2nd episode.

Resources