How can I check which page has sent the form? - ruby-on-rails

I want to be sure that the data I receive came from a specific page (it's for a navigator game).
I would prefer a solution using RoR but if we can do it with JS it's ok =)

In your controller, you have access to the request variable (type of ActionDispatch::Request) which represents the actual request received by your server:
def index
puts request.inspect # see in your server's console the output
# ...
end
With this variable, you can access to the referer, which returns the path (as String) of the last page seen, or nil if you came from another domain (or blank page).
To check which page sent your form, you could use:
def my_controller_action
if request.referer.present? && request.referer.include?('/string/to/check/')
# yay!
else
# well, the request is not coming from there
end
end
You could also set it as a before_filter in your controller in order to check "quietly" the requests and not in each controller's action.

Related

what to do to clear the query string in url ? Is redirection the only way?

My app is in rails .
I have a Get browser request coming(when user clicks a link in another website) to my app with important query string parameters like
http://example.com?logintoken=hjhzjkdhz .
But I feel that I should use this logintoken in my controller but don't want to show that to user on the browser url bar after rendering the page . so in short I want to show only http://example.com in url bar of browser finally.
Is there a way to just clear the query string ?
I see that redirection to http://example.com at the end is one way to achieve this .
Is there any other way ?
An alternative way to do this is to change your request to a POST and so hide the params in the message.
You can't do that without redirecting... Well, technically you can, if you manipulate browsers states after render (history push and pop).
On the rails side, you will need to redirect and pass your URL parameter to a server variable and redirect to the action, without the params, using these variables:
def myaction
if params.any?
session[:myaction_params]={}
session[:myaction_params]=params
redirect_to myaction_path
elsif session[:myaction_params] && session[:myaction_params].any?
# use your params like this
# params[:logintoken] will now be session[:myaction_params][:logintoken]
# apply logic here
else
# do something else if there are no params
# redirect_to somewhere
end
end

How can a flash message persist between requests in Rails?

A tutorial I am following has the below code which it mentions is not quite right because the error flash persists one request longer than desired because render doesn't count as a request. The solution is to use flash.now instead.
But how is it even possible for the error flash to persist one extra request? Given that Rails is stateless how is the information of the flash stored for the next request?
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
# Sign the user in and redirect to the user's show page.
else
flash[:error] = 'Invalid email/password combination' # Not quite right!
render 'new'
end
end
def destroy
end
end
Use flash.now instead of flash.
The flash variable is intended to be used before a redirect, and it persists on the resulting page for one request. This means that if we do not redirect, and instead simply render a page, the flash message will persist for two requests: it appears on the rendered page but is still waiting for a redirect (i.e., a second request), and thus the message will appear again if you click a link.
To avoid this weird behavior, when rendering rather than redirecting we use flash.now instead of flash.
The flash is stored in the user's Session, which is associated with them on subsequent requests using HTTP cookies. The flash is just one part of the session whose data is automatically flushed on the next request. See the Rails Guide to Action Controller for more details.

Rails flash hash being rendered one request too soon

I'm having an issue in Rails 3 where the flash hash seems to be returning things one request too early. That is, it seems to return things upon rendering that were set in that very same request. For example, consider a controller action that does:
add_warning "Danger, will robinson."
In my ApplicationController, I have:
before_filter :set_errors
#...
def set_errors
flash[:errors] ||= []
flash[:warnings] ||= []
flash[:notices] ||= []
end
#...
def add_warning(msg)
flash[:warnings] << msg
end
And my application.html.erb layout template has
<% flash[:warnings].each do |msg| %>
<div class="warnings"><%= msg %></div>
<% end %>
Based on what I'm understanding from the Rails guide, the flash contents shouldn't be rendered in this same request unless I'm using flash.now. And, if I have a redirect_to, they SHOULD be rendered in that second request. But they don't show up at all when the redirect_to happens.
flash.now need when you can't lost params[] for example: user filling the form for new post and have mistake in title for example (action new in Posts controller), he push submit and data send to create action, we have params[:post][:title] but if it's not valid and after we redirect to new action we already haven't params[:post][:title] and we can't fill field and user lost all filled data and user will be angry =) In this case, we use render and we still need to show warning, we use flash.now.
In other way we use just flash[] new action (1)-> create action (we set flash[] var) (2)-> index action we show flash[]. Like params in 1st example we lost flash[] after 2nd step.
Sorry for my pretty bad English, especially in long text.
flash and flash.now both render, but flash.now does so immediately, while plain old flash only renders after you redirect.
http://blog.vedanova.com/2010/09/29/rails-flash-now/
Based on your main question, it sounds like you want to use flash instead of flash.now
It turns out that the reason for the issue was the set_errors method, combined with my lack of understanding of how the flash hash works.
It seems that if a new value is not assigned to a key in flash, then the value of that key will be nil on the NEXT request. This may seem obvious, but the implications are subtle because I was assigning values to keys with ||= ("or-equals") on each request.
Consider the case where I have a series of requests to the same action, which don't ever call add_warning:
On the first request, flash is an empty hash. It contains no keys, so the ||= assigns some.
On the second request, flash is a hash with three keys, each value an empty array. Now, since each key has a value, the ||= does not assign anything. Which means that on the third request, rails has cleared those values and flash is an empty hash once again.
Now, consider this case:
On the first request, flash in an empty hash. It contains no keys, so the ||= assigns some.
On the second request, flash is a hash with three keys, each value an empty array. Now, an action calls add_error. However, an array already exists at flash[:warnings]. So, a value is pushed into that array. The contents of the array have changed, but the value of flash[:warnings] has not changed - it is still a reference to the same array. Hence, two implications:
The value of flash[:warnings] (i.e., the reference to an array) has not changed during this action, so because we've modified the same object that rails assigned to flash[:warnings] at the beginning of the request, it gets rendered with the newly pushed message at render time.
The value of flash[:warnings] (i.e., the reference to an array) has not changed during this action, so the action prompted by the next request will not have a :warnings key in flash at all.
So, in conclusion, the subtle point is that assigning a new value to a key in the flash hash is what causes it to be available in the following request.
EDIT: I guess it might help to post my solution, which is to eliminate the set_error and before_filter entirely, and instead to put the ||= [] fragment in the add_error method. That way, values are assigned to the flash hash only when they should be - when an error message is added.

rails not picking session data

I am implementing a payment gateway in my app.
Its like this:
The user fills the form with necessary details, along with a field containing return_url(say http://myapp.com/ebs_payment/ebs_response?dr={somedata}) and submit the form to a secure payment site. After the transaction is complete, the secure site puts some encrypted data into my param {dr} and the user is redirected back to the return url. The problem here is, when the user returns to the app with the return_url, the application fails to pick up the session data and returns a nil value.
Before submitting the form, I put the object #fdPaymentDets in to session.
Here is my controller:
class EbsPaymentController < ApplicationController
#before_filter :login_required,:check_user_authenticate
#access_control [:ebs_response] => ('user')
def ebs_response
#fdPaymentDets = session["fd_payment_details"]
#deal = Deal.find(#fdPaymentDets.deal_id)
#categories = find_all_categories
end
private
def find_all_categories
#sp = SitePreference.find(:first)
Category.find(:all,:limit => #sp.categories_display_limit,:order => 'position')
end
end
When the user is redirected to the return url (http://myapp.com/ebs_payment/ebs_response?dr={encrypted_data}) from the secure site, rails is not picking the #fdPaymentDets object from session and making it nil thus resulting in an error when accessing data from the nil object.
The surprising thing is that, when I put the same return_url in my browser by hand, the session data is neatly picked and everything goes well.
Am missing any thing here? What could be the obvious reason?
Any help appreciated.
Cookies and redirects are messy and bug prone (from a browser's implementation perspective).
Take a look at
Safari doesn't set Cookie but IE / FF does
Suggestion would be to change the implementation to set the session first in the show action, and then update the value before the redirect

getting the flash hash to persist through redirects

My basic use case is do some processing, set flash[:notice], and then redirect to a new page. From what I can tell, redirects reset the flash tag (please correct me if I'm wrong). Is there a way to gain persistence? Using sessions isn't an option, and I have hacked around the problem using cookies, but I think there's got to be a better way.
The flash hash persists for exactly one redirect or render. So you should be fine with the default settings.
If you need to keep the flash hash for another request/redirect, you can call flash.keep.
flash.keep # keep the entire flash hash around for an extra request.
flash.keep(:notice) # keep just flash[:notice] for an extra request.
Something to be aware of in at least Rails v3.2.1 is that the flash will persist through a redirect if its not referenced at all through at least 1 redirect and load the same view after. This is a pseudo code of my recent experience:
def some_action
(code that may set a flag to redirect 1 time)
redirect_to action_path if(redirect_flag)
....
end
Running this would result in the flash[:message] being present regardless of the redirect.
def some_action
logger.debug("Flash[:message] #{flash[:message]}")
(code that may set a flag to redirect 1 time)
redirect_to action_path if(redirect_flag)
....
end
During debugging with the logger referencing flash[] it would only show up when the redirect didn't happen. I could see this being problematic if you added a reference to flash before a redirect and lost it down the line for no apparent reason.
See ruby docs here (Instance protected method: Use at the bottom)

Resources