RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

Using rspec, I'm doing the following: (Geocoded Zipcode stores zipcode->lat/lon pairs)

ruby
gz = GeocodedZipcode.new(:zipcode => "12345", :latitude => "50.00", :longitude => "-75.00")
gz.stub!(:geocode).and_return(true)
gz.save!

I'm really not happy with this solution. Gotta be a better way.

Avatar

How are people who are using this testing? I'm trying to find the best place to insert a hook to prevent actual geocoding during my tests.

Avatar

Ryan, thanks for a great episode. I am curious, too, about the ins and outs of mounting the engine multiple times. I am not sure what the use case would be, but the question is an interesting one.

Avatar

@ Everyone trying to to this on Heroku I know I am late but I set up a new appspot app that uses the new version of Pygments and wrote a little blog post about how to use it at http://iamaust.in/posts/3.

I hope this helps people, now you can colorize things like coffeescript and sass for your rails 3.1 apps

Avatar

What if i have a main app that would like say multiple blogs provided through some mountable blog engine. Do I then have to mount the blog engine each time for each blog and with a different path each time?

ruby
mount Blogifier::Engine => '/blog'
mount Blogifier::Engine => '/blog2'
Avatar

@IanWhalen

automatically login after signup. Add the cookies line in the save condition.

ruby
  def create
    @user = User.new(params[:user])
    if @user.save
      redirect_to root_url, :notice => "Signed up!"
      cookies[:auth_token] = @user.auth_token
    else
      flash[:notice] = "User exists."
      redirect_to sign_in_path
    end
  end
Avatar

Not tested, but I think this should work:

ruby
mount Uhoh::Engine => '/', :constraints => { :subdomain => 'uhoh' } 
Avatar

Problem is solved, not sure exactly why, but I can run Capybara now.
It is much more strict than Webrat and I have discovered some bugs in my application which did not show up with Webrat.
Thanks for this great episode.

Avatar

You should always refresh a page before replying, just in case someone has already posted a more thorough explanation than yours :)

Avatar

I think it won't be a problem. In the assets directory of the engine, the path of the image is still "uhoh/alert.png", no matter what route the engine is mounted at.

Avatar

Thanks for the Railscast Ryan! I did my own "How I Test" including tests for both "remember me" and "forgot password" using Cucumber, email_spec, Delorean, etc. Hope this helps someone!

https://github.com/leesmith/decent_authentication

Avatar

Bravo!! Always been a big fan of Railscasts!
I'm wondering if there's an easy way to mount an engine into a subdomain, say, http://uhoh.example.com in this case?

Avatar

#249 deals with ActiveSupport Notification subscriptions, which this episode uses to catch exceptions.

#149 is relevant though, so I've added a link to it. Thanks.

Avatar

A little late to the party here, but...:
Scratchin' my noggin' about the asset pipline here...
do I set the Jasmine YAML to point to app/assets/javascript?
Also, a nice post here: http://blog.carbonfive.com/2011/07/06/pragmatic-javascript-testing-with-jasmine/
note at the bottom about the jasmine-headless-webkit allowing cli spec running and CoffeeScript interpretation.

Avatar

Ryan, I looked at the engine you guys made: say I make an engine, how much work does it then take to make this engine compatible with refinery? ... at first glance it seems your engine just blends right in with refinery, but I'm guessing there is more to it... can you say something bout this or is there anywhere I can read up on this?

Thanks in advance man... thanks for the example and thanks to the ryan that made this screencast... beauty as ever!

Avatar

Isn't that should be "Episode 149: Rails Engines" instead of "Episode 249: Notifications in Rails 3" in show notes ??

Avatar

@Thomas, if I understood correctly, that uhoh under "uhoh/alert.png" is independent from the route path, it refers to uhoh/app/assets/images/uhoh/alert.png, notice the extra uhoh folder after images/ (minute 11:40 to 11:50). So yes, it is "automatically" handled by Rails.

Ok, whatever...

Avatar

Currently Rack-Offline is broken for Chrome and Firefox. This is based around how it generates the hash in deployment. It is solved in this branch https://github.com/arsduo/rack-offline

Avatar

Just a note...

To use token input with simple_form, the user have to adapt the command, like this (in this case I did not use the attribute 'name' - for more details see the post above):

_form
<%= f.input :author_tokens, :label => "Author", :input_html => {"data-pre" => @book.authors.collect{|author| {:id => author.id, :name => author.nome}}).to_json %>
Avatar

Wow soooo awesome i always neglected engines but from now ill see how i can apply them to my apps

Avatar

Hi Ryan - nice 'Casts!

A suggestion/request for Railscasts: Any way you can add a link in each episode's "show notes" page to that episode's git source code page? That would make what is already an awesome resource even better!

Avatar

Everything is ok in development environment, having some problems in production: while the corresponding html (with its css) is exactly as it's supposed to be, the .pdf version seems to ignore css rules. Any suggestions?

Avatar

If you're planning to build gems from your engines, it may be worthwhile to start with the latest from 3-1-stable instead of RC5. The generated gemspec file is now much more complete, including details such as author, email and homepage. Also, it now contains dependencies which are included in the Gemfile via the gemspec command (similar to the "bundle gem" approach).

Avatar

Quick question.

Let's say that the author of the main app that uses the engine, decides to mount it under a different path.
For instance:

mount Uhoh::Engine => "/failures", :as => "uhoh"

How would this influence the assets used by the engine.
I imagine that the image at the top of the Uhoh failures page would fail, as the engine is no longer in the /uhoh path?

<%= image_tag "uhoh/alert.png" %>

Or is this handled automatically by Rails?

Avatar

Hi,
I too get the same error as vinaya has mentioned.

/Ruby/Gems/1.8/gems/activesupport-3.0.9/lib/active_support/xml_mini/rexml.rb:20:in `parse': uninitialized constant ActiveSupport::XmlMini_REXML::StringIO (NameError)

Please let me know if you find any fix for this issue?

Avatar

Interesting. I wonder why Rails is able to load assets and initializers and such, but not able to pick up the migrations... one would think it could just append the migration path to the list of places to search for and run from.

Avatar

Thanks Ryan for this screencast!

If people are interested to see what a bigger Rails 3.1 engine looks like, a few friends and I have built a forum system called forem: http://github.com/radar/forem. We would be happy to answer any questions anyone has about building an engine.

Avatar

Hi Peco,

You can put them in vendor/plugins or as gems, as long as they are in a position where the class inheriting from Rails::Engine is loaded then they should work as well either way.

I would personally recommend using gems though, as they have versioning support where plugins do not

Avatar

So, are these engines intended to be used as gems or they will live in the plugins directory?

Avatar

Engines look promising in Rails 3.1!

Wondering why you didn't use something like

ruby
rescue_from Exception, :with => :record_error

in the application controller. Is it so that the error is raised like it normally is?
In that case you could reraise it in record_error I think.

Avatar

Great tutorial, as always! Anybody knows of any good engines that can be mounted inside an rails app to handle the common stuff such as marketing pages / helpdesk?

Avatar

Thank you Ryan!

Is there a memory consumption overhead when bundling a plugin as an engine compared to, say, a gem? Has anyone benchmarked this?

Avatar

I have always been a big fan on Engines and use them religiously. All the love Engines are being shown in Rails 3.1 is getting me very excited for the final release.

Avatar

Do you see any risk in using this method? Might allow for private methods to be called? How would you mitigate this risk?

Avatar

Spork (which I'd installed beforehand together with autotest, webrat, and rspec) crashes.
Most probably I'm missing some code to make it run correctly with capybara.

Avatar

What's your problem? I'm using Rails 3.1 rc5 and it works perfectly.

What error do you get?

Avatar

I'm getting

undefined method 'session' for ApplicationController:Class

EDIT: I managed to get this working by stubbing the current_user method

ApplicationController.stub(:current_user).and_return(user)

Avatar

I'm using this to practice

Avatar

Is there a particular obvious or elegant solution for automatically logging in a user upon registration? I do love to build from scratch as much as possible, but that is one thing which other gems do seem to provide that this does not.

Avatar

@Steve - I just had the same problem and was searching for the fix. Thankfully your note re: enabling javascript seemed to work for me. Just added this to the head of application.html.erb

<%= javascript_include_tag :defaults %>

Once that was in, things worked fine. Unfortunately I'm a relative noob to this, so don't have any other suggestions here.

Good luck

Avatar

I can't get the timecop to work in my application.
I hope you guys know what's wrong. I've used Ryans code.
What I see is that the reloaded object has nil for the password_reset_sent_at attribute.

I get:
1) User#send_password_reset saves the time the password reset was sent
Failure/Error: user.reload.password_reset_sent_at.should eq(Time.zone.now)

   expected Fri, 31 Dec -0001 23:40:28 UTC +00:00
        got nil

   (compared using ==)
 # ./spec/models/user_spec.rb:24:in `block (3 levels) in <top (required)>'
ruby
# user_spec.rb
    it "saves the time the password reset was sent" do
      Timecop.freeze
      user.send_password_reset

      puts 'printing user password_reset_sent_at'
      p user.password_reset_sent_at
      puts 'printing reloaded user password_reset_sent_at'
      p user.reload.password_reset_sent_at
      puts 'printing last user password_reset_sent_at'
      p User.last.password_reset_sent_at
      user.reload.password_reset_sent_at.should eq(Time.zone.now)
    end

# user.rb (model)
  def send_password_reset
    generate_token(:password_reset_token)
    self.password_reset_sent_at = Time.zone.now
    save!
    UserMailer.password_reset(self).deliver
  end

stdout:
printing user password_reset_sent_at
Fri, 31 Dec -0001 23:40:28 UTC +00:00
printing reloaded user password_reset_sent_at
nil
printing last user password_reset_sent_at
nil

Avatar

You might want to look into Ernie Miller's Ransack gem https://github.com/ernie/ransack

Avatar

Gread episode, thanks!

I have just one problem with this line:
mail.body.encoded.should match(edit_password_reset_path(user.password_reset_token))

It failed with:

ruby
1) UserMailer password_reset_email send user password reset url
     Failure/Error: mail.body.encoded.should match(edit_password_reset_path(user.password_reset_token))
     NameError:
       undefined local variable or method `controller' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_1:0x00000106264150>
     # (eval):10:in `edit_password_reset_path'

It looks like I cannot use paths in mailer spec. Im using
rails 3.0.9,
rspec (2.6.0)
rspec-core (2.6.4, 2.6.3)
rspec-expectations (2.6.0)
rspec-mocks (2.6.0)
rspec-rails (2.6.1)

Could somebody help me to deal with this?

Avatar

Try ApplicationController.session[:key].

Avatar

so i got mine to work simple quirk just needs a space newline between the code block and preview text

Avatar

I'm having the same problem with any form submited data, works fine if i manually enter it into my database

Avatar

when I got to the SSL portion of the screencast, everything worked fine in Safari with the same sort of message "Safari can't open page".

however when I switched to Firefox, the error message is quite diff't:

"Secure Connection Failed

An error occurred during a connection to localhost:3000.

SSL received a record that exceeded the maximum permissible length.

(Error code: ssl_error_rx_record_too_long)"

Likewise the log output from the server, which on Safari was:

Started GET "/login" for 127.0.0.1 at 2011-07-28 21:44:32 -0500
  Processing by SessionsController#new as HTML
Redirected to https://localhost:3000/login
Completed 301 Moved Permanently in 1ms
[2011-07-28 21:44:32] ERROR bad URI `?,rz?7?1\x00\x00H\x00??'.
[2011-07-28 21:44:56] ERROR bad URI `?????>]\x03????X?y?\x00\x00H\x00??'.
cache: [GET /login] miss

now, in Firefox , looks like:

Started GET "/login" for 127.0.0.1 at 2011-07-28 21:46:06 -0500
  Processing by SessionsController#new as HTML
Redirected to https://localhost:3000/login
Completed 301 Moved Permanently in 0ms
[2011-07-28 21:46:06] ERROR bad URI `|a\x00\x00F?'.
[2011-07-28 21:46:06] ERROR bad Request-Line `\x16\x03\x00\x00Q\x01\x00\x00M\x03\x00N2\x1E?][4\x01\x00??u?9^?!RY?g0??%?H?\b?\x00\x00&\x00/\x00\x05\x00\x04\x005\x00'.
[2011-07-28 21:47:06] ERROR bad Request-Line `\x16\x03\x01\x00?\x01\x00\x00?\x03\x01N2\x1F*\x10?o-k\eD?\x7F?T??u?9?\eN\x01?.???\x12\x00\x00H\x00??'.

Is this as expected? I note that both say redirected to the SSL equivalent. But the Safari message looks legit whereas the Firefox one looks like more of an error

Edit @sethvargo - fixed code formatting

Avatar

thanks, Tim.. That cleared things up.