Rails - How do I refresh a page without reloading it? - ruby-on-rails

Rails - How do I refresh a page without reloading it ?
I'm building an app which has a function that gives out a random number (random record) every time people go to that page, but the problem is that when user goes to that page, a random number is given but that number will change again if the user refresh the page.
How do keep that random number even when user refresh the page or comes back to that page, the random number stays the same.
I'm thinking disabling the refresh functionality in browsers which will stop users from refreshing the page hence stop them from changing the random number but after researching, it looks like it is a good idea to disabling the refresh functionality.
Is there any other methods to achieve it?
----Update----
I have tried
#posts_controller.rb
def new
#random = cookies[:stuff] ||= Stuff.random
end
and call #random.content in my view since I want only the content of the Stuff model, the first time is fine but when I refresh the page, it gives me undefined method 'content' for "#<Stuff:0x0000010331ac00>":String What's going on?

You could do this in your controller action:
# ex. app/controllers/index_controller.rb
def index
session[:random] ||= rand(10000)
end
This would generate a random number between 0 and 10000 and save it in the user's session, only if it wasn't already present before. This means that it will be the same for each specific user until he closes his browser.
If you want persist even after closing the browser then you could use cookies instead:
cookies[:random] ||= rand(10000)
You can replace the rand(10000) call by whatever custom method you want.

Related

Sharing the variables between the actions in the controller in Rails

I am working on a module where I have to take the consent of the user to save the set of records.
those set of records are created in an action, which has to be made available in another action of the same controller, the records are being saved by the user consent.
now I can send these set of records to UI, from UI to again controller, if the user continues to save, if not cancel.
Problem is there will be thousands of records, which is painful to carry between UI and controller so My plan is to make the set of records available to the action which is being called by the continue button
the code
def create
#valid_members = generate_member_upload_results(params[:member_upload_user][:members_list])
end
in this action #valid_members is going to have the set of records. after this action executes in UI we will ask user whether the records are to be saved if no then cancels if yes then the following action will takes palce
def create_member
count = 0
unless #valid_members.blank?
#valid_members.each do |m|
count = count + 1
m.save(:validate => false)
end
end
redirect_to :back , notice:'#{count} members records created'
end
I want my #valid member should the same object which I used in create def.
I'm not entirely sure this is feasible with the flow you're suggesting. This sounds like something that could be resolved with a multi-step form but you would need to pass the data across or temporarily store it, which is seemingly what you're trying to avoid.
Alternatively, can you create a Rails endpoint that services the first step via javascript directly from the frontend? That can return the data without the user leaving the page, they can then confirm they are happy and submit the page once with approval.

How to elegant the first time show popup with Rails

I have to show user a popup for the first time they come to my site.
I did it that way,
When the user comes in the first time, the cookies has nothing,
so I will show popup, and save a flag to cookie.
The next time user comes, the popup won't show.
However, I think my implementation smells bad, seems not in a Rails way.
How can I improve it ?
View
- unless #has_shown_price_hint
:javascript
$("#hint_for_price").fadeToggle(2000);
document.cookie="has_shown_hint_for_price=true";
Controller
def index
#has_shown_price_hint = (cookies['has_shown_hint_for_price'].nil?)? false : true
end
In my opinion you can add login counter to user. It's a great idea by itself to know how loyal your users are.
Then checking if the user is the first-time visitor is just checking condition:
def first_time_visitor?
login_count == 0
end

Unable to log out and redirect to new page from yielded layout

In a 3.2.16 Rails app using Devise, we allow users to stay logged in for a number of days. This means, of course, that if they click a link to our page (say in their bookmarks) they come right back into the app (assuming their session is still active).
For our main screen, we have a yielding layout
...
<body>
...
<%= yield %>
...
</body>
The layout surrounding the yield includes a display of the username among other things.
And now I have a new controller:
class AccountSelectionsController < ApplicationController
def new
if user_signed_in?
sign_out current_user
current_user = nil
end
...
render :layout => "external"
end
...
end
When the new action is invoked, I want the user signed out completely, the session cleared, and the user taken to a completely different layout. The use-case assumes the user is reaching this controller from a link in, say, an email or a page outside my app (IOW, not from a spot inside my app).
I first thought I merely had do a sign_out current_user(as above), but that didn't do anything obvious: the user seems to stay signed in.
The above was just my starting point. I've tried just sign_out (without a resource, implying all scopes), reset session, and redirect_to destroy_user_session_path (which is what our standard logout button does, a button positioned on the surrounding layout).
What I got though was my new external view (or the normal new session sign in screen, depending on the permutation of what I tried) trying to render inside the old layout (as if it was part of the yield).
I could try the Devise after_sign_out_path_for to help with redirect, but then I'd only want it if it was tied to this particular controller and action and I'm not quite sure how to safely accomplish that. And now I'm not convinced it wouldn't just keep me wrapped in the surrounding layout anyway.
So, (1) is there a reason the main layout stays intact even upon a full redirect_to (even using :status => 301) that I should be able to defeat (for instance, is the yield interfering?), or (2) am I on the right track with Devise after_sign_out_path_for and what do I need to do to limit that behavior to just respond to this one controller action?
Thank you!
Richard
UPDATE: the served page (via view source) shows the intended screen body is wrapped within the layout of the origin screen
UPDATE 2: I've also tried returning a head :reset_content from a before filter along with various other things in a before_filter. Still the old layout keeps rendering before it attempts to render the new page. This is although I'm using different Chrome tabs in the test (i.e., the session stays in memory); I've tried it in Firefox too. Same result. The output of rails s shows the redirects and gives no indication that it's attempting to go through another controller first, something is triggering the layout. Is there away to force a layout in a redirect?
Try this instead,
sign_out current_user, :bypass => true
So this is my penance for posting the question.
I just figured out that a before_filter was intercepting the call to the controller and redirecting it to the wrong layout before a sign-in was ever checked for. Normally this is desired for this particular application, but I didn't realize that the filter actually was catching the redirect ahead of my controller (the logs suggested it happened at a later point). Once I set that filter to be skipped in my controller, all was well.
Moral of the story, I need to better consider the side effects of before_filters in the ApplicationController.
Thank you to RSB and Jasdeep Singh and everyone else who spent time considering an answer for this.

How to trigger modal when event occurs in Rails

I'm sure that there is an answer to this out there, but I'm not entirely certain how to properly phrase this question, so my apologies if this is repetitious.
I am working on implementing a badge/achievement system for a site. The backend stuff is there, but I'm working on the front-end now, and I'm basically trying to figure out how to redirect to a sort of "Congratulations!" page when someone gets a new badge.
The congratulations page is going to be a modal, but for simplicities sake, if anyone has an idea of how to trigger an action like this only once when a new Badge is created, that would be a huge help. Right now, when a user performs a given action, say... adding money to their account, a user_badge is created (adds a Badge ID to an array).
Thanks in advance!
You can use before_filter for actions, where you want to check that new badge appears (probably you don't want to check it in auth actions, so you can't use global before_filter). Then you can use redirect_to in this before filter, if user has a new badge.
But I don't recommend to do so, since you'll break the users flow. It's better to show alert/modal on the next requested page. To achieve this you can define a new instance variable in your before_filter (like #show_modal) and include the partial with modal to your footer.
example:
#before filter
def check_for_new_badges
if current_user.has_new_badges?
#show_modal = true
current_user.set_badges_as_seen!
end
end
#included in layout
- if #show_modal
= render 'shared/congrats_modal'

How to persist data about what page you are on in Rails app

This will probably be easiest if I explain what I'm trying to do. I have three actions in my Rails app controller, each rendering a different page. The page-render is done with a single partial which uses variables that were set in the controller action code. For example, each page has a list on it, but on one page the list is sortable. Up to now I've been handling this by setting a #sortable flag to true or false in the code for my actions.
This works fine when an action is initially run. The problem is that I have AJAX stuff going on (e.g. adding a new element to the list) and when this happens, I need to know the value of the #sortable variable again. It seems to have gone, even though I'm still technically on the same page. What I want is a variable store that is linked to the page you are on.
What are your recommendations for doing this? (Storing it in the Rails session hash seems like overkill - too much chance that the wrong value will get left in there by some yet-to-be-implemented action.)
Ben
In rails I've only managed to set page scoped variables for initial setup too.
I think the only solution would be to pass the sortable flag from the page on the ajax request. You can store it either with a javascript variable, in a hidden field, custom attribute on your list or anyway you wish and then in the ajax you simply add that to the request so you can treat that on the server side persistently.
Why do you don't want use session? As for me before_filter works fine for such tasks
in ApplicationController
before_filter :init_actions
def init_actions
session[:action] = action_name
session[:controller] = controller_name
end

Resources