I have what should be a relatively simple form in Rails that I'm using to send an email for two different previews, a desktop preview and a mobile preview.
<form id="email-form" role="form" action="<%= action_name == 'desktop_preview' ? email_preview_newsletter_path(#newsletter) : email_preview_newsletter_path(#newsletter, mobile: 'true') %>">
<label for="email_address">Email</label>
<input type="email" id="email_address" name="email_address" value="<%= params[:email_address] %>" placeholder="PLEASE ENTER EMAIL">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<input type="submit" value="Send" class="btn btn-primary"></input>
</form>
Right now I have it setup so that both previews get sent to the same endpoint, '/email_preview', but in the case of the mobile_preview I want to pass in a 'mobile' query string so that it ends up looking like this:
'/email_preview?mobile=true'
When I inspect the form on the page everything looks in order, however when it gets passed to the controller the 'mobile' part of the query string disappears and only the 'email_address' exists.
I suppose I could pass in the mobile value as a hidden field, but something about that just doesn't feel right to me. What is the best way to setup this form so that both the 'mobile' and 'email_address' key value pairs are passed as query strings when sent to the controller?
In the process of writing out this question I realized exactly what the problem was:
I had the form setup as a GET request as opposed to a POST request.
This was causing any pre-established query strings to get erased in the process of setting up the GET params being defined in the form (in this case, the 'email_address' param). Changing the form from GET to POST, (i.e. form method="POST")
Took care of this issue. Please note that if you are going to manually setup a form like this in rails then you also need to explicitly take care of the csrf token. This can be done by inserting the following input with the helper method into your form:
input type="hidden" name="authenticity_token" value="<%=form_authenticity_token%>"
Related
I have a hidden field like this in my view:
#Html.HiddenFor(m => m.Url)
then i have a form in which i'm posting the data via Ajax call like this:
<form id="formdata">
<input class="btn primary" type="submit" value="Submit" onclick="submitForm('#Url.RouteUrl("createAccount/"+ '#Html.HiddenFor(m => m.Url)'+ )'">
</form>
How do i Pass the url from the hidden form into my submit function. I'm not sure if i have to use double quotes or single quotes around it? or is this achievable?
Thank you
HtmlHelper.HiddenFor used for creating hidden field with specified value assigned to viewmodel binder, instead of rendering its value directly. What you need is using Model.Url property to pass viewmodel property into JS function like this:
<input class="btn primary" type="submit" value="Submit"
onclick="submitForm('#Url.RouteUrl("createAccount/" + Model.Url)')">
In case it returns encoded URL containing query string, use Html.Raw() i.e. Html.Raw(Model.Url).
NB: You can use AjaxHelper.BeginForm to submit a form through AJAX as alternative to handling submit button click event & using jQuery.ajax with passed URL.
On a particular page in my website, there are a variety of potential URL parameters:
http://www.example.com/my_webpage?at=2014-01-01&page=5
Now I want a simple way to add a parameter to that like this:
http://www.example.com/my_webpage?at=2014-01-01&page=5&records=100
So I tried the following HTML with embedded Ruby:
<form action="<%= request.original_url %>" method="get"># of records <input type="text" name="records"/></form>
The problem is the resulting page that opens is:
http://www.example.com/my_webpage?records=100
Essentially, the old parameters get wiped away. What's an easy way to retain them? I could loop through the params hash and add hidden_tags (I'd have to selectively exclude params not part of the request params), but I would expect with such a common use case scenario there's a better easier way.
While there isn't an easy Rails way of doing this automatically, Rails does provide access to the request parameters through the request.query_parameters hash. So I simply needed to add this in the form:
<% request.query_parameters.each do |key, val|%>
<input type="hidden" name="<%= key %>" value="<%= val %>"/>
<% end %>
when I submit one page to another, the sites shows the information!
Someone told me to use post to avoid it. however, when I use post method it doesn't work.
<form action="\look\at", method="post">
Select your new car's color.
<br>
<input type="radio" name="radios1" value="red">red
<input type="radio" name="radios1" value="green">green
<input type="radio" name="radios1" value="blue">blue
<br>
<br>
<input type="submit"/>
</form>
When I submit I can not see \look\at page. but I delete method="post" It works well.
How I use post method?
Check your routes (in config/routes.rb).
Probably you will have a line
get '/look/at', to: 'look#at'
replace get by post and it will accept a post.
Since you are not using the rails form helper or view mechanism (erb/haml) (please start using them, why write plain html????), you have to skip the authenticity token check (please note that this check is there for a reason: it is a protection against cross-site request forgery).
Just add the following line at the top of your controller:
skip_before_filter :verify_authenticity_token
I am using Sinatra but I am guessing this also applies to Rails (if not, please remove the tag or let me know and I will remove it).
I have a ActiveRecord::Base class User. It has tons of attributes and I am displaying a page that will allow someone to update the a particular user. Problem is, I have a hard time implementing the update functionality in a DRY manner. What I mean is, when I get the params with a POST request, I can do:
a_user.update_attributes params
because params contains bnch of other crap too (like :splat - what's that?) and it will throw an unknown attribute error. What I instead have to do is this:
a_user.update_attributes {:attrA => params[:attrA],
:attrB => params[:attrB], ...etc }
(keep in mind there are A LOT of attributes)
Is this how I should do this? To me, for some reason...it doesn't feel right. If for example, I have another Model that needs to be updated in a similar manner, I have to rewrite manually all attributes again.
What I am looking for is somethign like:
a_user.filter_and_update_attributes params
where filter_and_update_attributes automatically filters params of any bad/unknown attributes and I can use this anywhere with any models with have to rewrite so much useless code.
Thanks
If you structure your form like this:
<form action="/users" method="post">
<input id="user_email" name="user[email]" type="text">
<input id="user_name" name="user[name]" type="text">
<input id="user_phone_number" name="user[phone_number]" type="text">
...
<input id="user_email" name="user[email]" type="text">
<input name="commit" type="submit" value="Submit">
</form>
you should be able to use the params like this:
#user.update_attributes params[:user]
When you name your html fields like user[email], the params hash looks like:
{ user: { email: "example#example.com", name: "Example" } }
So using params[:user] gets you that nested hash of parameters that belong to the user.
You can filter a hash using select. Find a list of all attributes of your model and test if the keys are in that list:
attrs = a_user.attributes.keys - User.protected_attributes.to_a
a_user.update_attributes params.select {|k,v| attrs.include?(k)}
After the user has logged in and their username authenticated and saved in session[:user_name], when submitting a form with method="post" (using standard html) all session data is cleared and user is routed back to the login page. This does not happen if the method is set to get.
Post works when I use the rails "form_tag" which generates these additional lines:
<div style="margin: 0pt; padding: 0pt; display: inline;">
<input type="hidden" value="✓" name="utf8">
<input type="hidden" value="a_bunch_of_gibberish" name="authenticity_token">
</div>
What is happening?
Are you using Rails 3.0.4? It sounds like it might be related to the CSRF fix.
If you need a fix specific to your needs, you can overwrite #handle_unverified_request in your controller. See https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/request_forgery_protection.rb.
Here's an example where this issue was with OmniAuth and OpenId. (See section 'CSRF Protection In Rails 3.0.4')
This issue can also happen if you're creating your own html form.
If you're getting redirected without knowing why, it's because of "protect_from_forgery" in your ApplicationController
In order to allow your form to post, add the following code to it (or use form_tag, explanation below):
<form ... >
...
<%= hidden_field_tag "authenticity_token", form_authenticity_token %>
...
</form>
The reason the "form_tag" works is because form_tag generates the hidden field for you =)