Redirect to another model's index action, and hence view index.erb - Rhomobile - ruby

I am developing a Rhomobile application,on submit of a POST method, i am going to my 'Model 1' action, after execution of my action i want to redirect to another model's (Model 2) Index action and list the data.
I am from a Rails background, there i would have used URL, any similar concept exists here or any solution.
i tried, but it didn't worked for me render :controller => :model2, :action => :index

Please Note: I have never used rhodes and all of this information was acquired by simply reading the API documentation and taking a look at the source code.
According to the documentation You should be able to deal with this in a very railsy fashion eg
def some_action
redirect controller: :model2, action: :index
end
Seems the only caveat is if this redirection is to happen in a callback function. In this case the redirection should be handled by the WebView instead e.g.
Rho::WebView.navigate(url_for(controller: :model2 action: :index))
Source for Rho::RhoController#redirect supports these statements in the documentation.
Additionally as you might notice above it appears that Rho has ported a lot of the rails like helpers including url_for

Related

rails not routing https

The following rails routes.rb file
resources :aggregators, :constraints => { :protocol => "https"} do
collection do
get :confirm
post :send_sms
end
member do
post :confirmed
post :failed
post :cancelled
end
end
is not being called. When a form calls one of these actions,
<%= form_for(#aggregator) do |f| %>
the user gets bounced to the root page of the application. In comparing with and without the constraints, the non-https activity picks up
Started POST [...]
Processing by AggregatorsController#create as HTML
whereas the https version
Started POST [...]
Processing by AggregatorsController#index as HTML
So clearly the routing is missing the create action. (the bouncing back to home is an applicationController method which aplies a policy on the index action) I assumed it would be an integral part of resources. What am I doing wrong? Better yet I only want to invoke https on specific actions and would like to keep the focus on new, create and confirm...

rails different form_for parameters for different tasks?

I have the following two form_for() that I am confused about.
# form for users
form_for(#user) do |f|
# form for sessions
form_for(:sessions, url: login_path) do |f|
I understand that the first one is simply go through all the users and input the form. I am not sure why when you create a new session, the parameters for form_for is listed as such. Why is there a login path?
Michael Hartl explained it as "in the case of sessions we need to indicate the name of the resource and the corresponding URL", but that doesnt' really explain anything to me.
any enlightenment would be nice!
Passing :url to form_for method is optional when dealing with a model object. when using it to create a new object:
# long-style:
form_for(#user, url: users_path)
# same thing, short-style (record identification gets used)
form_for(#user)
In the short-style version a concept called Record Indentification is used, basically rails figures out if the record is new by asking record.new_record? It also selects the correct path to submit to based on the class of the object, in this case #user.class
Same principle applies when using form_for when updating an existing object. In this case the record.new_record? returns false, and rails figures out it must submit the form to the update action of the controller.
In cases when the path that the form must submit to cannot be figured out by rails using the above mechanism, then the url must be provided explicitly. This also applies when defining Singular Resources such as resource :geocoder. when creating forms for singular routes, the URL must be specified:
form_for #geocoder, url: geocoder_path do |f|
In the first case, the form_for helper inspects the #user variable to see its state. The User might be a new record (in which case the form points to /users with POST*) or an existing record (users/:id with PATCH). It can also provide pre-filled inputs based on the variable's state.
The second form is used when there's no need for an instance of a model (or maybe the model doesn't even exists) and the form_for helper is used just for convenience. The url parameter is explicitly set because by default the action would point to the current URL and you want it to point to login_path.
*Technically they are both POST on the browser side, Rails will distinguish between them later.

Grab Facebook signed_request with Sinatra

I'm trying to figure out whether or not a user likes our brand page. Based off of that, we want to show either a like button or some 'thank you' text.
I'm working with a sinatra application hosted on heroku.
I tried the code from this thread: Decoding Facebook's signed request in Ruby/Sinatra
However, it doesn't seem to grab the signed_request and I can't figure out why.
I have the following methods:
get "/tab" do
#encoded_request = params[:signed_request]
#json_request = decode_data(#encoded_request)
#signed_request = Crack::JSON.parse(#json_request)
erb :index
end
# used by Canvas apps - redirect the POST to be a regular GET
post "/tab" do
#encoded_request = params[:signed_request]
#json_request = decode_data(#encoded_request)
#signed_request = Crack::JSON.parse(#json_request)
redirect '/tab'
end
I also have the helper messages from that thread, as they seem to make sense to me:
helpers do
def base64_url_decode(payload)
encoded_str = payload.gsub('-','+').gsub('_','/')
encoded_str += '=' while !(encoded_str.size % 4).zero?
Base64.decode64(encoded_str)
end
def decode_data(signed_request)
payload = signed_request.split('.')
data = base64_url_decode(payload)
end
end
However, when I just do
#encoded_request = params[:signed_request]
and read that out in my view with:
<%= #encoded_request %>
I get nothing at all.
Shouldn't this return at least something? My app seems to be crashing because well, there's nothing to be decoded.
I can't seem to find a lot of information about this around the internet so I'd be glad if someone could help me out.
Are there better ways to know whether or not a user likes our page? Or, is this the way to go and am I just overlooking something obvious?
Thanks!
The hint should be in your app crashing because there's nothing to decode.
I suspect the parameters get lost when redirecting. Think about it at the HTTP level:
The client posts to /tab with the signed_request in the params.
The app parses the signed_request and stores the result in instance variables.
The app redirects to /tab, i.e. sends a response with code 302 (or similar) and a Location header pointing to /tab. This completes the request/response cycle and the instance variables get discarded.
The client makes a new request: a GET to /tab. Because of the way redirects work, this will no longer have the params that were sent with the original POST.
The app tries to parse the signed_request param but crashes because no such param was sent.
The simplest solution would be to just render the template in response to the POST instead of redirecting.
If you really need to redirect, you need to carefully pass along the signed_request as query parameters in the redirect path. At least that's a solution I've used in the past. There may be simpler ways to solve this, or libraries that handle some of this for you.

Passing Sinatra models and validation

As mentioned on another similar thread I started recently, I am porting an ASP MVC application to Sinatra, partly for learning, partly for production purposes.
Currently my ASP MVC application has no views, it just exposes models as Xml/Json etc and accepts them in the same way. So in the scenario of someone sending a model to the server, it would auto bind the object, perform validation then return validation errors if there are any, if not carry on with the relevant actions.
Now in Sinatra it is a bit more barebones that ASP MVC which is a great thing as I have more choice on how to do these parts, however I dont have a clue what gems/libraries functionality is available for doing this.
My ideal scenario would be I have my pure html/js front end posting a model as json and then have it turned into an actual model where I can validate it (through Sinatra or other framework) then make a decision based on the validation results.
Try taking a look at this gem:
json
Then what you should be able to do is pass in the attributes for an object you would like to create as a hash of attributes converted to a json object:
{:attribute1 => "value1", :attribute2 => "value2"}.to_json
And on your Sinatra app, catch them and build the object from those attributes, and you can use Sinatra to validate as well:
def '/create_object' do
content_type :json
obj = Object.new(JSON.parse(params[:object]))
if obj.save
obj.to_json
else
error 400, user.errors.to_json
end
end
Sounds like an ordinary case for an ORM. So you could for example use DataMapper. With that in your hands, you can simply send a form via HTTP to a specific route and do something like:
post '/create' do
#post = Post.new(params[:your_form])
if #post.save
erb :a_template
else
erb :your_form
end
end
Where params[:your_form] is a hash containing the contents of your form. No JSON needed at all. If the saving process fails (for validation reason or whatever), the model object #post will have errors, which you could process in a different view (:your_form for example).
Best Regards
Tobias

Manual POST request

Scenario: I have logged into a website, gained cookies etc, got to a particular webpage with a form + hidden fields. I now want to be able to create my own http post with my own hidden form data instead of what is on the webpage and verify the response instead of using the one on the webpage.
Reason: Testing against pre-existing data (I know, I know) which could be different on each environment hence no predictable way to use it. We need a workaround.
Is there any way to do this without manually editing the existing form and submitting that? Feels a little 'hacky'.
Ideally, I would like to say something like:
browser.post 'url', 'field1=test&field2=abc'
I would probably switch to mechanize to muck around at the protocol level. Something like this added to your script
b = WWW::Mechanize.new
b.get('http://yoursite.com/current_page') do |page|
# Submit the login form
my_form = page.form_with(:action => '/post/url') do |f|
f.form_loginname = 'tim'
f.form_pw = 'password'
end.click_button
end

Resources