RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

I updated my timer app over the weekend. The app runs fine, but my Capybara integration test of a PUT link now fails (it worked in Rails 3.0). Capybara also does not show the styles when using save_and_open_page, so I'm guessing that Capybara does not play well with the asset pipeline (yet?). I was hoping Ryan would re-run his tests in the video after he moved his Javascripts and styles to app/assets.

Avatar

Hi Ryan,

I just came up with the following code to help ensure that you get consistent ID's when using the delete and repopulate seed approach.

ruby
Model.delete_all
Model.accessible_attributes<<"id"
Model.create([{id: 1, ...},
{id: 2, ...},
{id: 3, ...},
...
]
MessageType.accessible_attributes-["id"]
Avatar

Hi Ryan,
One quick question.. I was able to upgrade my application successfully, though I am facing 1 issue. When I run my app in the production mode (rails s -e production) for some reason my view helpers are not included even though I have helper :all in the application_controller.rb file.. Any hints as to why that is happening?

Thanks
Priyanka

Avatar

Hello, movie was cropped.
Would you adjust the width of screencasts?

Avatar

Well, a benefit of the asset pipeline is md5 fingerprinting of the images...

Avatar

Nice tuts..

By the by, how can I do this?

I have my assets folder structure like this

assets
javascripts
products
--product.js
--productValidate.js
store
--store.js

I want the project.js and projectValidate.js to be added in my application.js as a part of asset pipe-lining only when actions in product controller is called and store.js when actions in store controller is called.

Avatar

I just finish migrating one of my projects and also discovered that in rails 3.1 they deprecated RAILS_ROOT in favour of Rails.root,RAILS_ENV in favour of Rails.env, and
RAILS_DEFAULT_LOGGER in favour of Rails.logge

I made the changes and the project seems to be working properly.

Thanks for the info Ryan.

Avatar

Bastien was already pointed at this issue, you need to apply patch from there

Avatar

If you're not using ActiveRecord or you're skipping some other default Rails module, there's another gotcha in application.rb. For example, you can cherry-pick which modules you want to use by requiring them explicitly:

ruby
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"

If the top of your application.rb doesn't say require rails/all, make sure you add this line:

ruby
require "sprockets/railtie"
Avatar

Why not simply move the images folder into the public directory? What's the downside of not having images go through the asset pipeline? Or rather, what's the benefit of using the asset pipeline for images too?

The main reason I can think of would be to always get the right path, regardless of which directory structure the app is installed in, but that seems like a relatively minor problem to have.

Avatar

Is it possible through template inheritance to make dynamic navigation...

Say that I had a blog application with a list of categories and wanted to link to those categories to show list of articles within those categories, could I use a dynamic method to create the links to the categories show page and place that in an inherited template?

Avatar

Thanks ! Really clear. The only thing I had issue with is replacing the .rjs by new jquery code. As I created some template rendered .js.erb, I won't get anymore any error on javascript... I suppose it's because the js is rendered but I'd like to know if there was some setting to debug those with error message like in rjs before ?

Avatar

Just for more info...what I'm doing at the moment is just referencing /assets/application.css from my error pages. This works; however:

  1. It's unclear to me why it works; it seems rails has some sort of fallback if an asset isn't found in the public/assets directory. Which leads to...

  2. This file gets served from rails (I can see it happening in the production.log file), rather than "normal" assets that get served from the web server from the public/assets directory that's created during asset precompilation. So, for example, if rails is totally hosed and throwing exceptions, my 500.html isn't going to work.

Hmm.

Avatar

What are you planning to do for your 404.html and 500.html pages? I'm using the default asset pipeline settings (e.g. digests, don't allow fallback), and I use my application's CSS file inside those error pages.

The problem is, in production I don't know what the filename for that CSS file will be, since it's using a digest. And I want to keep my 500 page as just static HTML, without any processing on the server, so using the normal rails stylesheet link tags is out.

Any ideas? I hate to just copy the CSS I need...

Avatar

Hi all,

First thanks Ryan. Railscasts are excellent. I've learnt so much from you.

I'm fairly new to Rails (been learning the last few months) so I haven't had any real exposure to Rails 2.

I'm trying to recreate this tutorial in Rails 3 and I think I'm having trouble with the routes.rb file. This line:

current_cart 'cart', :controller => 'carts', :action => 'show', :id => 'current'

In the show code the method looks like it's in application.rb.

I'm trying to ge this working in Rails 3.0.10 and ruby 1.9.2p290

Can anyone help me correct code in the function for rails 3 and fix my routes.rb?

Thanks,

Chris.

Avatar

I'm just learning rails so I'm sure this is a real novice mistake but I've gotten to where I have created a twitter dev account and added the consumer_key and consumer consumer_secret to the omniauth.rb file.

My link is setup like this:
<%= link_to "Sign in with Twitter", 'https://api.twitter.com/oauth/authorize' %>

But I'm receiving an error message from twitter:
"Woah there! This page requires some information that was not provided. Please return to the site that sent you to this page and try again

Avatar

You should be careful with that bundle update - if you run it, not only will rails and its dependencies be updated, but also everything else. If you are not careful with the version numbers you specifiy in your Gemfile, you might end up with potentially breaking updates of the gems you're depending upon. I think for updating Rails it's better to first bundle update rails. If everything works, go on and update all your other gems.

Avatar

Thanks as always Ryan for a great screencast. Are there any know gem incompatibilities with the new rails 3.1? E.g. We use refinerycms a lot and there it seems it is not compatiable out of the box yet.

Cheers Juergen

Avatar

Thank Ryan.
Does Rails 3.1 can use the gem for rails 3.0 ?

Avatar

ah.. thanks for that. had been using filename.css.erb and asset_data_uri().
wasn't very happy with that solution.

Avatar

How about images referenced inside of your css (or js) files? Is there a better solution than rename these files to .css.erb and using the image_tag inside of them?

Avatar

The download links appear to be missing. Here's a link to the MP4 version.

Avatar

Thanks! config.assets.compile = true + config.assets.digest = true saved my day. Lost hours yesterday figuring out, why stylesheet_link_tag 'application' had refused to link /assets/application-md5hash.css...

Avatar

Having a check in the edit action makes it more convenient.

However you should NOT remove the check from the update action, as attackers can now try outdated activation codes forever with forged PUT requests.

Avatar

Don't forget to git commit new files as you develop with bundler! I forgot this aspect and found myself lost for a few hours when the files I was requiring in my lib/some_gem_name file were not available in the gem!

Avatar

This is awesome. Ryan, How to use Jasmine in Rails 3.1?

Again, Thanks for all! :)

Avatar

I had to delete request.port_string from the with_subdomain join function in Rails 3.1 as the request.domain already included it, so I was getting :3000:3000

Avatar

Hi Ryan. Having an issue with seeding and I wondered if you could shed some light. I am seeding my database (with no issues) other than the before filters are not called when seeding. Is there anyway of doing the rake db:migrate call and ensuring before filters are called?

Avatar

@ryan is there any reason why in the PasswordResetsController you perform the 2 hour check in the update action and not in the edit action? It seems counter-intuitive to have the user post a new password, and then inform them that the password reset token has expired. Is there any reason why you wouldn't do it like this?

ruby
class PasswordResetsController < ApplicationController
  
  def new
  end
  
  def create
    user = User.find_by_email(params[:email])
    user.send_password_reset if user
    redirect_to root_url, :notice => "Password reset instructions sent by email."
  end
  
  def edit
    @user = User.find_by_password_reset_token!(params[:id])
    if @user.password_reset_sent_at < 2.hours.ago
      redirect_to new_password_reset_path, :alert => "Password reset has expired, please request another reset."
    end
  end
  
  def update
    @user = User.find_by_password_reset_token!(params[:id])
    if @user.update_attributes(params[:user])
      redirect_to root_url, :notice => "Password has been reset."
    else
      render :edit
    end
  end
  
end

And thanks for showing us this, I've now ditched Devise and feel cleansed.

Avatar

i have the same concern, since it is quite possible to brute force many ids in password_resets/id/edit and then set the users password AND email to your own pw & email.

If you could not assign an email via the password_resets_controller, then it would be much harder to figure out which email was assigned to the updated password.

Avatar

After export to upstart and running this command

start testapp

I am getting this error

start: Job failed to start

I am using Ubuntu 10.4 LTS and logged in with root if it does matter.

Avatar

for anybody having the same problem with testing, when switching from session to cookies. You need to use request.cookies to assign the cookie.

ruby
RSpec.configure do |config|
  def test_sign_in(user)
    request.cookies[:auth_token] = @user.auth_token
  end
end

and in your normal specs where you use test_sign_in

ruby
request.cookies[:auth_token].should == @user.auth_token

in specs where you dont use test_sign_in but rather post :create, :email => "user@example.com", :password => "somepassword"

ruby
cookies[:auth_token].should == @user.auth_token

its really confusing me

Avatar

irb + rails debugger =pry...awesome.. makes life much easier..!

Avatar

I was talking about the interface the developer uses. The implementation under the hood is the same as ryan's.. or similarish. the point is that it is under the hood.

Avatar

Using rails 3.1 for creating and running the engine gives me the following error.
"couldn't find file 'jquery'"
I have jquery-rails as dependency in the gemspec file and the gem is installed.

I get the same error for both the engine and the dummy app.
I've asked in both ruby-forum and on IRC but no one seems to know anything about it.

http://www.ruby-forum.com/topic/2484569

Would be great if someone could shed some light on this matter :)

Avatar

Hi Joe, I'm getting

undefined method `user' for nil:NilClass

This seems to be an issue with request.env['warden'].user - any ideas?

Avatar

A slight improvement:

ruby
Resque::Server.use(Rack::Auth::Basic) do |user, password|
  if ['admin'].include? user do
    [SALTED_HASH] == BCrypt::Engine.hash_secret(password, [SALT])
  end
end

Since it's a mounted sinatra app, I guess inheriting from AdminController won't be possible?

Avatar

Here's how I hardened the login via resque_auth.rb. You'll need the bcrypt-ruby gem installed.

  • Fire up IRB or PRY
  • require 'bcrypt'
  • Generate a salt: salt = BCrypt::Engine.generate_salt
  • puts salt // make sure you copy this somewhere.
  • Now, salted_hash = BCrypt::Engine.hash_secret("YOUR PASSWORD GOES HERE", salt)
  • make sure you save the longer output!

Update resque_auth.rb as follows:

ruby
Resque::Server.use(Rack::Auth::Basic) do |user, password|
  
  [SALTED_HASH] == BCrypt::Engine.hash_secret(password, [SALT])
  
end

Make sure you replace the above respectively. Voila!

Avatar

@Paolo Well, this is very slow, and sometimes hanging for 10 sec. Use pygmentize gem instead

Avatar

You can just type reload! in Pry as you are used to

Avatar

i put under app/assets/javascripts/application.js(includes "function remove_fields(link)"and"function add_fields(link, association, content)") ,

Avatar

How can I retain a select value after error validation ? :contact_purpose value is gone after validation failed. I have this code into a form:

.emails
= f.fields_for :emails do |builder|
%p
= builder.label :email, "New Contact Email:"
= builder.text_field :email
= builder.select :contact_purpose, options_for_select([['Select', 0], ['Home', 'Home'], ['Work', 'Work']])
= builder.link_to_remove "Remove"
%p= f.link_to_add "Add an Email", :emails

Avatar

where did you put nested_form.js ? it might go under vendor/assets/javascript and be required in application.js as

//= require jquery.min
//= require jquery-ui.min
//= require jquery_ujs
//= require nested_form
//= require_tree .

Avatar

Here's another tip: Foreman runs anywhere. I currently use it in a non-Rails folder to get it to start up 2 Rails apps that need to run at the same time. Example:

yaml
web: cd site; bundle exec rails s
worker: cd site; rake jobs:work
search: cd site; bundle exec rake sunspot:solr:run
scheduler: cd redirect; rake jobs:work
log: tail -f site/log/development.log
Avatar

I don`t want to use 'find_by_sql', but currently it is the only way to get ordered relation for pagination. It would be good to use 'last' and 'first' methods.

I have modelname.where(...).union(modelname.where(...))
how i can get something like modelname.where(...).union(modelname.where(...)).order('something')?