RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

Once again, nice screencast!

However, I think you have too much logic inside te password_resets_controller. Especially the 2.hours part. Now for small apps this might not be a big problem, but otherwise, I would create something like a PasswordReset class in the model directory to handle this logic for me.

And I agree with @introspectif that Devise is childishly easy to customize. So much so that I would never write my own authentication. There are too many security pitfalls to remember.

Avatar

Also, about Devise, it's an engine, so changing views or controllers is as simple as putting them directly in your app. With rails engines, what's in your app takes precedence over what's in the engine. If you have no view for X, the it takes it from the engine. If you do, it uses yours. I like the idea of building things from scratch (this is a great episode) and minimizing plugin bloat, but it's worth mentioning.

Avatar

Since rails detects and rejects cookies that have been tampered with, could we just use the user id rather than the auth_token, and put it in a signed cookie? Or, since sessions seem to actually be signed cookies (no?), is there a way in rails to just directly extend the expiration of the session cookie (if there's nothing else we keep in the session that we want to expire sooner)?

Avatar

I was wondering if scoping is possible with eager loading. Without using scope things work fine, but when scoping is introduced new queries get fired.
Problem in detail : here

Avatar

Hi Ryan,

You mentioned it is important to name the field password_digest when you created the model. However then the model/view/controller uses password. Does rails somehow know how to match password to password_digest?

If I use a name pass_digest, would rails match to pass?

Avatar

Hi Ryan,

In staging/production passenger doesn't serve up the static assets associated with the resque server after mounting it in routes.rb. Otherwise, it works just fine, just no styles/javascript. Is there a workaround for this?

Thanks!

Avatar

I was wondering if scoping is possible with eager loading. Without using scope things work fine, but when scoping is introduced new queries get fired.
Problem in detail : here

Avatar

Check this out:
You can easily get associated model data into Jason

http://stackoverflow.com/questions/4764954/getting-value-from-associated-model

Then within token-field you can add a function to manipulate your entries

javascript
onResult: function (results) {
      $.each(results, function (index, value) {
        value.name = value.quantity + ': ' + value.name;
      });
      return results;
    }
Avatar

The method you describe is more susceptible to SQL injection, in my opinion. It's better to compare in the code instead of letting the DB do the authenticating. This also benefits from separation of concerns, the DB is responsible for storing and retrieving data not authenticating a user.

Avatar

tried this under rails 3.1 and get

rails
    'uninitialized constant JSON::ParserError
    Rails.root: /Users/marc/src/rails/sample3.1

    Application Trace | Framework Trace | Full Trace
    app/controllers/locations_controller.rb:20:in `create'
    This error occurred while loading the following files:
       multi_json/engines/json_gem'

Any ideas?

Edit: fixed formatting - @sethvargo

Avatar

To do this with heroku, change syntax_highlighter to the following:

ruby
  def syntax_highlighter(html)
    doc = Nokogiri::HTML(html)
    doc.search("//pre[@lang]").each do |pre|
      lang = pre[:lang]
      code = pre.text.rstrip
      request = Net::HTTP.post_form(URI.parse('http://pygments.appspot.com/'), {'lang'=>lang, 'code'=>code})
      pre.replace request.body
    end
    doc.to_s
  end
Avatar

thank's a million for this post!! I had spent lot of my time trying to find out what went wrong...U R AN ANGEL helmerj!!!

By the way...what has h() to do with the problem...!! Everything was going fine till the end of tutorial but i was stuck on this last part. Could you please elaborate the h(). I'm kind'a new rider in rails!!
:p eace!!

Avatar

Is there any way to send the PDF generation to a background process like delayed job?

Avatar

Big fan of Resque (and RailsCasts!).

Here's a slight modification to Arcath's CanCan support to check if a user can manage Resque instead of relying on route checking.

http://www.simple10.com/resque-admin-in-rails-3-routes-with-cancan/

Avatar

Hey thanks for that info, I'll have to do some research on this geospatial datastore

Avatar

In general I think of single-precision floats as being precise to approximately a city block. Double-precision floats should be accurate to within inches.

Calculations with decimals are slower so I don't recommend them unless you need some really extreme precision (in which case you should probably be using a proper geospatial datastore).

Avatar

Ryan, maybe it'll be useful to include the routes.rb file in the show notes.

Avatar

Thank you very much for this tutorial Ryan!!

Just one quick question: Is there any way to adapt this solution to 'simple_form'?

Thanks in advance!!

Avatar

For those getting the js-rendered HTML auto-escaped, I've solved like this:

  • First, if you're using Rails 3.0.8 there's a bug which prevents html_safe and/or escape_javascript to work correctly. Just update to 3.0.9.

  • Second, in the line in application_helper:
    link_to_function(name, h("add_fields(this, '#{association}', '#{escape_javascript(fields)}')"))

you should remove the h() method call, which double escape the HTML, causing the problem.

Thanks for your great screencasts.

Avatar

Ryan, Thanks. Your screencasts have helped me such a great deal.

Does anyone have inputs on how to find businesses between two points/along the path ?

Avatar

Hello, Ryan.

Five days ago I installed gmaps4rails gem and, since then, I'm very happy with it. So I feel compelled to testify about its easiness of use, specially with maps handling.

Just out of the box, gmaps4rails offers the ability to show a collection of items in a map, which, by the way, is also easy to set with a helper method.

I don't know if this "is" Google API or gmaps4rails, but the default map groups the items when you zoom out.

I believe that, by the default, geocoding happens after validations. And you can set your callback method.

So, Ryan, could you please make a screencast about gmaps4rails?
Thanks!

Avatar

Awesome screencast, maybe you could expand with a multiple upload one :)

Avatar

I think GeoKit uses MySQL specific calculations to find nearest destinations.

Avatar

Geokit wasn't working in Rails 3, when we tried to use it earlier this year.

Avatar

For a production grade environment, on an Ubuntu server, I installed redis on its own:

sudo apt-get install redis-server

which then also gave me the 'redis' script in /etc/init.d, let things run in the background, etc. Though, note that the redis.conf get's put in /etc/redis/redis.conf.

Avatar

There is a /public directory inside resque's gem directory, and you need to symlink it to your application's /public directory.

That, or change this line:

config.serve_static_assets = true

in your config/production.rb file.

Having no desire to make/let rails serve assets, I went with the former option.

Avatar

This comment is slightly implementation specific, but if anyone is trying to use Postgres with Passenger for a production environment, Resque workers seems to lose their DB connections when the forking happens.
see
https://github.com/rails/rails/issues/1339

Basically, everything can still work properly, but your resque.rake file needs to be setup like this:

require 'resque/tasks'
require 'resque_scheduler/tasks'

task "resque:setup" => :environment do  
  Resque.before_fork = Proc.new { ActiveRecord::Base.establish_connection }
end
Avatar

If only I had known about this gem before I finished my collegiate capstone project. =(

Oh well, still won the contest =P

Avatar

Hi, I have been trying to create a multistep Form (referencing episode #217) and my form has nested attributes as in episode #196.

I have merged the idea from both of these episodes.And I am in problem.
I have two Models.
Models
1) Event has_many: invitations
accepts_nested_attributes_for : invitation,:dependent=>:destroy

2) Invitation belongs_to: event

Controller --Event

ruby
 def new
    @event = Event.new
    2.times {@event.invitations.build}
  end

  def create
    @event = Event.create(params[:event])
     if @event.save
    @event.next_step
    render "new"

View:Event(new)

rails
<%= simple_form_for @event do |e| %>
  <%= render "#{@event.current_step}_step",:e=>e %>
<%end%>

<%= link_to "Back to List", events_path %>

MY PROBLEM :: WHEN I GO TO next_step...the view nor show the nested_field atrributes NOR it shows any error..it simply skips the entire nested form fields....i'm going nuts...how can it simply skip the code!! any idea!!

Avatar

I'm trying to implement this, but I'm stuck. I am carrying a param from a previous page to the index, and when I click on "Search" I get the error "Couldn't find Sla without an ID"... I know I'm doing something dumb, but can someone help me?

Controller:

ruby
class PeriodBillingsController < ApplicationController
  def index
    @sla = Sla.find(params[:sla_id])
    @search = PeriodBilling.latest_billing.search(params[:search])
    @period_billings = @search.order("we_date desc").where("sla_id = ?", @sla.id)
  end  
end

And the view:

rails
  <%= form_for @search do |f| %>
    <%= f.label :pe_number_eq, "Period #" %>
    <%= select("period_billing", "pe_number", (1..12), {:include_blank => true}) %>
        <%= f.label :appcode_eq, "Appcode" %>
    <%= collection_select( "period_billing", "appcode_id", Appcode.where("sla_id = ?", @sla.id), :id, :appcode, :include_blank => true ) %>
        <%= f.label :dpc_employee_eq, "Named Resource" %>
    <%= collection_select( "period_billing", "dpc_employee_id", DpcEmployee.all, :id, :fullname, :include_blank => true ) %>
    <%= f.submit "Filter Records" %>
  <% end %>

Thanks in advance for any help....

Avatar

(I know this cast is old, but I am really new to Rails!)
You are saying that everything that is stored in session is encrypted. However, here, it says that

The client can see everything you store in a session, because it is stored in clear-text (actually Base64-encoded, so not encrypted)

and

There are, however, derivatives of CookieStore which encrypt the session hash, so the client cannot see it.

So, I am a little bit confused about whether a client can read the session hash or not.

BTW. While waiting for your answer, I found this.

Avatar

I've recently found *= depend_on "users" no longer works. Appending the file extension seems to get it working again :)

Sorry if someone has already posted this.

Avatar

Sorry for those who's using Prototype! Never a mention for Mootools users! :D

Avatar

Thanks,
I did look through the source and found that I can pass the unit I want as an options hash allowing me to provider user switching in the future.

ruby
Location.near(params[:search], 50, {:order => :distance, :units => :km})
Avatar

I was under the impression that you should use a decimal data type when storing the latitude and longitude because a float isn't precise enough, what are your thoughts on this?

Avatar

What if the way that your app is making money isn't from the Google Maps data? For example:

If I had an ecommerce site as well as chain of retail stores and I wanted to use the Google Maps API for something like a Store Locator. Would I still still need to have said license?

Avatar

You can use

ruby
Geocoder::Calculations.to_miles(km)
Avatar

Awesome cast, concise and clear.

been playing with the gem but cannot figure out how to change from miles to km or is this even an option?

Avatar

Geocoder is lighter, easier to use, and has features missing from GeoKit like built-in result caching. It's also designed to be compatible with more storage engines (like MongoDB) and environments (JRuby, Rack, SQLite, etc).

GeoKit has been around longer but Geocoder is also production quality.

Avatar

Geocoder currently supports Google, Yahoo, Bing, Yandex and Geocoder.ca APIs for street address geocoding. Geocoder.ca is free but only provides data for the US and Canada. Easy enough to configure:

ruby
Geocoder::Configuration.lookup = :geocoder_ca

The Geocoder README has a table comparing the features of the various APIs.

Avatar

Hi Ryan,

Thanks for the useful cast.
But i struck with it in my project. I used one of your cast to insert multiple tasks for a project through javascript, in that insert tasks by javascript you used date time to replace the child_index for form_for tag.

Here i got the validator objects but as the name of the fields changes it can't validate those.

Can you please help me in solving this problem.

Avatar

I saw Maxsy's problems, too.
How can I fix it?

moderator edit: Aug 14, 2011

Avatar

Can you share your helper in a gist?

Avatar

I use my own helper to put the map code into the head via content for. The gem isn't worth the hassle IMO.

Avatar

A bit annoying, but yield does not work from helpers. Taken from the API docs:

`Note: yield can still be used to retrieve the stored content, but calling yield doesn

Avatar

What opensource provider would you suggest? I looked at mapquest but their api hasn't changed since august '10.

Otherwise openlayers looks really bad.

If I had a good alternative to google, I'd update my gem to implement it.

Avatar

I cant install redcarpet, im using windows :(! "Error: Failed to build gem native extensions." Someone could?

Avatar

The crappy thing about using the Google Maps API is that there is a commercial restriction on the data. If your app makes money, then you need a license, which will run you $10K/year. Ouch!