I'm writing a simple app that takes standard input from the user. As for the email entry, I have it verify if it is in a standard email format and then have it list the problems like this when a new instance is going to be saved:
u = User.new
u.email = params[:email]
u.save
if u.save
redirect '/'
else
u.errors.each do |e|
puts e
end
end
I know that if it is correct it should return back to the home page. If it is wrong I want it to return to the home page as well, but I want it to return an error value (so I can have a pop-up or just something onscreen letting the user know that the format of the email was wrong). What would be the best way to do this?
You can use the 'sinatra-flash' gem to display all kinds of errors/notices etc.
u = User.new
u.email = params[:email]
u.save
if u.save
redirect '/'
else
flash[:error] = "Format of the email was wrong."
redirect '/'
end
Then you need to say where you want the flash[:error] to be displayed. Normally I put this in the layout.haml or (erb) file right above where I yield in the content.
layout.haml:
- if flash[:error]
%p
= flash[:error]
Also, make sure you include the gem and enable sessions
require 'sinatra'
require 'sinatra/flash'
enable :sessions
You could also try the 'rack-flash' gem. There is a tutorial for using it at http://ididitmyway.heroku.com/past/2011/3/15/rack_flash_/
You can save a potentially costly trip back and forth by doing it in Javascript. The way I see it, simple validation like this is a client function, handled by some code attached to an onBlur event, not something I need to verify on my side (except for sanitization, obviously).
To directly answer your question, I've used regular instance variables to store an "error array" in #errors. Form-specific errors, or errors that need to be displayed in a certain place on the page, rather than at the top, get stored in #form_errors or something similar. Then the template checks to see if there are errors and renders them accordingly.
Related
I'm having a problem with redirecting my website to a different page, if the person is younger then a certain age. Either, I need more coffee or I've lost it, I can't seem to see what I did wrong. Thanks so much.
app/models/student.rb
Im trying to sent people to a different site with redirect
private
def must_be_over_13
if birthday && birthday > 13.years.ago
redirect_to under_13_landing_page_path ``
end
end
I defined under_13_landing_page
controller/student controller
def under_13_landing_page
end
views/students
I made the redirect page
under_13_landing_page.html
config/routes.rb
I told it to redirect it to the landing page
get "games_for_kids", to: "students#under_13_landing_page", as: 'under_13_landing_page'
THE ERROR**undefined local variable or method `under_13_landing_page_path' for #**
rendering and redirection are Controller's responsibility NOT Model's. You should not be redirecting in the Model app/models/student.rb. This is the reason of the code failure as Model doesn't have access to the route helper methods such as under_13_landing_page_path in your case.
I would suggest you to return a boolean value from Student#must_be_over_13 method which you can then check in the concerned controller and redirect appropriately.
i can find a page I'm looking for just fine, like this:
#my_page = ::Refinery::Page.find('foo')
so then i can say <% link_to #my_page.url %>
i then try and protect against the case where that page is deleted, like so:
if ::Refinery::Page.find('foo').present?
#my_page = ::Refinery::Page.find('foo')
else
#my_page = nil
end
i've actually tries several ways of doing this, with exists?, with nil?, etc. the above is the most basic.
So I then go and delete my page and I get a record not found error.
Couldn't find Refinery::Page with id=foo
Shouldn't the present? method protect against that error? How should I be doing that?
When you do
#my_page = ::Refinery::Page.find('foo')
it tries to find page by slug first and if it doesn't find it then it tries to find it by id.
If you don't deal with localization you can do
#my_page = ::Refinery::Page.find_by_slug('foo')
which will return page if it finds it or nil if it doesn't.
With localization it get's complicated but this should do the trick
if ::Refinery::Page::Translation.find_by_slug('foo').present?
#my_page = ::Refinery::Page::Translation.find_by_slug('foo').refinery_page
end
How about following the principles of EAFP?
begin
#my_page = Refinery::Page.find('foo')
rescue ActiveRecord::RecordNotFound
#my_page = nil
end
I have an application that collect user input and store to DB and show back to user.
One user entered "alert(1)" into the name field and saved it into DB.
Whenever the name is displayed, the page will be broken.
I know how to fix that input only with validation for input, and h() for output.
However, I have so many input fields and so many outputs that accept users' text.
Is there any simple way to prevent this happening(i.e. overriding params method, etc)?
I also want to know how you expert guys are dealing with this problem?
As of Rails 3, my understanding was that embedded ruby code was html escaped by default. You don't need to use h() to make it that way. That is, if you use <%= "<script>a=1/0;</script>" %> in a view, the string is going to be made html safe, and so the script doesn't execute. You would have to specifically use raw() or something similar to avoid it - which you should naturally not do unless you're really confident about the contents.
For output, Rails 3 automatically html-encode all text unless I use raw() method.
For input, How about making a common validator and apply to all fields that are text or string? Is it desirable?
http://api.rubyonrails.org/classes/ActiveModel/Validator.html
class MyValidator < ActiveModel::Validator
def validate(record)
record.class.columns.each do |c|
if c.type==:text || c.type == :string
record.errors.add c.type, "script tag is not allowed" if c[/<script[^>]*>/]
end
end
end
end
I have a rails app and when I have both the console and db:console open, they have different values for what is supposed to be the same field. I am using the send function to change the value. Here is the method in the model:
def toggle_approve(field)
self.send(field)
if(self.send(field).blank?)
self.send(field + '=', "new_value")
puts self.send(field)
else
self.send(req + '=', "")
end
rank.save
end
In my db:console (sqllite) everything is always correct, but in my regular erb console it is wrong. My view will then show what is in the erb console and not the sqllite. I dont understand what is going on in the background that would causing this issue. Any help would be great.
It's hard to be sure from the details you provided, but I think it is the case that your view uses an obsolete version of the data. Try calling .reload on the updated record, just at the point after the update and before presentation. See if that fixes your problem.
I'm building an app on Rails 3 RC. I understand the point behind the _snowman param (http://railssnowman.info/)...however, I have a search form which makes a GET request to the index. Therefore, submitting the form is creating the following query string:
?_snowman=☃&search=Box
I don't know that supporting UTF encoding is as important as a clean query string for this particular form. (Perhaps I'm just too much of a perfectionist...hehe) Is there some way to remove the _snowman param for just this form? I'd rather not convert the form to a POST request to hide the snowman, but I'd also prefer it not be in my query string. Any thoughts?
You can avoid the snowman (now a checkmark) in Rails 3 by.... not using Rails for the search form. Instead of using form_tag, write your own as outlined in:
Rails 3 UTF-8 query string showing up in URL?
Rails helpers are great unless they're not helping. Do-it-yourself is good as long as you understand the consequences, and are willing to maintain it in the future.
I believe the snowman has to be sent over the wire to ensure your data is being encoded properly, which means you can't really remove the snowman input from forms. Since, it's being sent in your GET request, it will have to be appended to the URL.
I suppose you could write some javascript to clean up the URL once the search page loads, or you could setup a redirect to the equivalent URL minus the snowman. Both options don't really feel right to me.
Also, it doesn't seem there is any way to configure Rails to not output it. If you really wanted to get rid of it, you could comment out those lines in Rails' source (the committed patches at the bottom of railssnowman.info should lead you to the files and line numbers). This adds some maintenance chores for you when you upgrade Rails. Perhaps you can submit a patch to be able to turn this off?
EDIT: Looks like they just switched it to what looks like a checkmark instead of a snowman.
EDIT: Oops, back to a snowman.
In Rails 4.1 you can use the option :enforce_utf8 => false to disable utf8 input tag.
However I want to use this in Rails 3, so I monkey-patched my Rails. I put the following in the config/initializers directory.
# allow removing utf8 using enforce_utf8, remove after Rails 4.1
module ActionView
module Helpers
module FormTagHelper
def extra_tags_for_form(html_options)
authenticity_token = html_options.delete("authenticity_token")
method = html_options.delete("method").to_s
method_tag = case method
when /^get$/i # must be case-insensitive, but can't use downcase as might be nil
html_options["method"] = "get"
''
when /^post$/i, "", nil
html_options["method"] = "post"
token_tag(authenticity_token)
else
html_options["method"] = "post"
tag(:input, :type => "hidden", :name => "_method", :value => method) + token_tag(authenticity_token)
end
enforce_utf8 = html_options.delete("enforce_utf8") { true }
tags = (enforce_utf8 ? utf8_enforcer_tag : ''.html_safe) << method_tag
content_tag(:div, tags, :style => 'margin:0;padding:0;display:inline')
end
end
end
end