Lazy registration with RESTful routing in Rails - ruby-on-rails

I'm stuck figuring out the best practice...
I want to create a "following" system in a way that a user can follow a car (getting email updates when car price changes, etc). The part of implementation that's giving me headaches is when I want to introduce lazy registration by only using email.
Everything needs to work as AJAX requests.
In the interface, there will be a button to trigger the follow action, which will check if the user is registered or not. If a user is logged in, create a new CarSubscription item, otherwise display a form where he could type his email address. Once submitted, the form should create a user with no password (if email exists, ask for the password and log in) and then it should create the relationship item.
The challenge here is to use redirection after submission of the form to the CREATE action of the CarSubscriptionController. Since I can't redirect using POST I can't simulate the CREATE or DESTROY action.
The non-RESTful solution would be to create 2 actions under cars_controller: follow and unfollow and let them do the logic of creating entries and deleting them. That would enable me to just store the request path and use it after the user enters their email and logs in.
How can I achieve what I want using RESTful resources?
After trying to describe my problem here, it seems it's way too complicated and I am indeed very stuck... There are 3 different controllers and possibly 4 requests in this scenario.
Any help would be tremendously appreciated!
Please see my flow chart below:

Not an expert here, I don't know if it's the best solution, but what I have done in similar situation is :
In your controller, respond with javascript instead of redirecting the user
In your javascript file, use $.post(...) to issue a POST to your controller action
Et voilà!
You can also use ActiveResource to achieve this, but I actually never tried that solution : http://api.rubyonrails.org/classes/ActiveResource/Base.html#label-Custom+REST+methods
Person.new(:name => 'Ryan').post(:register)
Hope this helps

I had a very similar need and had trouble pulling the various bits of info on how to do this with Devise and Rails together into a working example. Here's a fully working example based on Rails 4, Ruby 2, and Devise 3.0:
https://github.com/mwlang/lazy_registration_demos

Related

How to make a private chat between 2 users in Rails?

Let's say I have Blog app built with Rails and on a post created by a user(Author) I have a "Request a chat" button.
I want to build a small function on that post page that when User A presses that button, the page will redirect to or open a chatbox that connect User A with user Author?
Author is a devise registered user and User A is not.
How would I build something like that? Thanks
I think it's weird having a devise registered user and a non devise user unless you mean User A is just an unregistered guest. Either way, it's not a big deal and it can be done.
The way you would put together that system is as follows:
OpenChat # your new data model
OpenChatsController # your new controller
"Request a chat" would create a new OpenChat object, with author and guest A foreign keys. If User A is a guest, you can store a cookie "password" in their browser but generally it's only advisable if the conversation is brief and security isn't a big deal.
Then you would be able to check if there is an open chat between the two users and display it in any page you want, and display messages appropriately.
You will need to look up how to setup a basic chat system (there are a million answers out there that will take you step by step) as that's beyond the scope of this question.
If you are new to Rails, I also recommend Michael Hartl's Ruby on Rails tutorial:
https://www.railstutorial.org/

Keeping POST data during sign up with Devise

I might be approaching this problem the wrong way ... so if you have a more elegant solution I'm all ears.
Imagine I'm making a system like Kickstarter. I want my users to be able to specify how much they want to pledge before I ask them to sign up.
Then, if they're not registered I need them to sign up before putting them back in the flow that they would have been on had they just signed in. Devise makes this easy by redirecting a user back to the after_sign_up_path_for which ends up being after_sign_in_path_for by default.
So this will always issue a GET request. But if I have data that I received from the POST with the amount they wanted to pledge, but that's lost.
Is the only way to do this to store that posted data in the session? Or is there a clever way to start creating the pledge record without the user (without needing to run jobs to destroy orphaned pledge records)?
I found the approach described in this blog post over at highgroove.com quite interesting in this regard: 
http://highgroove.com/articles/2012/10/09/lazy-user-registration-for-rails-apps.html
The basic idea is to always have an anonymous user at hand, even if the current vistor is not registered. Like this you can create e.g. associations as usual and — once the visitor actually does sign–up — you edit the user rather than all associated objects.
If the user does not ever register, you can simply look for abandoned user accounts and delete them including their associations, rather than look for all kind of abandoned models.

Ruby on Rails Sessions for new users

We have some sharing elements of our application where we embed logging IDs into the URL's that we share out. When a user clicks that URL, we add a record to our database so we can hopefully follow them throughout the registration process. We've found that if you reset your browser and go to the link the first time, there is no session info from the controller. However, all subsequent requests then have the session. It's almost like it's getting created after the first request.
We attempted to log it via ajax on the view, but this is cumbersome in all the places we want.
Anyone know what sessions wouldn't be available in the controller on first access for a new uesr?
I think you might have code in the wrong order. You must have the session creation before any logic can my applied to it.
Hope this helps.

Misc account management pages in a RESTful design in Rails 3

How do miscellaneous account management pages fit into a RESTful design in Rails 3?
For example, a user registers (create action) and is then forwarded to a registration success page (? action) where they are asked to now verify their email address via a url with a token (emailed to them).
When they click the link in the email, technically they are "updating" their account as part of the verification process right? So I'm thinking that would somehow map to the "update" action but the update action is expecting a PUT request. Is that correct? How do you make that work via the email?
I'm also wondering how forgot password, reset password, etc also fit into a RESTful design? Just trying to wrap my head around this.
Just because you have a result design, doesn't mean you HAVE to restrict yourself to only CRUD verbs that map 1:1 to Get/Post/Put/Delete. That said, if you want to get really RESTful, you can start to think of some of these things in terms of being their own resources. For example user verification:
User signs up, and gets sent a verification email, you already have that all squared away RESTfully it looks like
Verification url looks like: http://app.com/user_verifications/new?token=foobar (GET)
They follow the url and maybe are presented with a "Hello Dan, welcome back! Click here to verify your account" at that point you submit a form to http://app.com/user_verifications to trigger the create action there. Now on the backend, you can perform whatever actions you want, updating the user, setting them to active, or actually creating a "UserVerification" model.
Not a perfect example, but the idea is that the RESTful interface you are providing has an additional resource, in this case "user_verifications" and a user is acting upon it via HTTP methods in order to achieve the user's goals. You can apply similar logic to reset/forgot password either with a "UserSession" type resource or even as specific as a specific "ForgotPassword" resource.
Success page is just create.html.erb file. Usually you are redirecting from create action, but here you can just render success template.
Verifying. If you want to stay REST you should add one more step: GET verify, where is the form with your token present, which will lead to PUT update action. User recieves a link to this page.
But I prefer to use simple GET request here, which will update information without any additional clicks.
The same way you work with restoring passwords and other functionality. You add a page to with form that gets email, then you send a letter with link to a page with form filled with tokens and so on.

How do I implement gradual engagement using Devise and Rails 3?

I'm trying to implement a delayed-signup (aka delayed authentication aka gradual engagement) website flow using Devise + Rails.
By gradual engagement, I mean
"Don't make the user sign in until she
absolutely has to, but let her play
around and be remembered on the site"
I'm looking for a simple way to do this using devise. I feel like this is something many others have had to do, but I haven't found documentation on it.
The following approach sounds ok in my head, so I'm going to start with it:
Create users that are only "rememberable"
When certain pages are accessed, require that these users have more
data on them, like a username and
password, via something like
"before_filter :authenticate_user!" in
the appropriate controllers.
Does this approach make sense? Is there a better one? Do you have an implementation of a gradual engagement approach to signup/registration forms using Devise + Rails that you're willing to share?
I think the point of the article you gave us is to say:
only ask for sign up if necessary.
What does this mean?
Let's take an example. You're an e-commerce web site.
When does the customer has to sign up "at last"? During checkout. Never before. So you don't have to store, or remember anything about the user. Devise is never, never used here.
How do you manage the shopping cart of an unsigned in/up user? I'd say database, with session Id as primary key. Or You could store all the items ids in cookie, for later use.
In your code, if you have an action called checkout, just set in your controller a before_filter authenticate_user!, :only => [:checkout]
But maybe you have some constraints, like being able to keep your user's nickname without signing him up for example?
One alternate option is to do email-only signup, then send an email with a special link to finish registration later / bring them back to their account. There's an actively maintained tutorial on devise email-only signup at:
https://github.com/plataformatec/devise/wiki/How-To:-Email-only-sign-up
I've used this tutorial for a site I did a while back where we only asked for their email address to sign up, then later sent emails for them to complete registration / add a password.
You can keep all unsigned user's data in cookies, and transfer them to database once the user logs in, if you need to.

Resources