RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

This code repeats 3 times. I've made press_enter method:

ruby
def press_enter( ch, stream, data)
  if data =~ /Press.\[ENTER\].to.continue/
    # prompt, and then send the response to the remote process
    ch.send_data( "\n")
  else
    # use the default handler for all other text
    Capistrano::Configuration.default_io_proc.call( ch, stream, data)
  end
end

I don't like to press Enter every time, so I've used ch.send_data( "\n") code.

Then you can use it like that:

ruby
run "#{sudo} add-apt-repository ppa:pitti/postgresql", pty: true do |ch, stream, data|
  press_enter( ch, stream, data)
end
Avatar

I have the same concern, is something about performance or better practices? Anyone?

Thanks for the episode!

Avatar

if I use:
save!(validate: false)
the test will pass. Using the above will not validate anything in the send_password_reset method. Is there's any danger of invalid information being saved to the database?!

Avatar

the problem is with send_password_reset method:
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
save! # this line will raise the exception
UserMailer.password_reset(self).deliver
end

before the method saves it has to set/(leave the same) the :password and :password_confirmation!

how do you do that...?

Avatar

Wow, this is great.

I was spending so much time trying to get my head around that exact problem (tracking order status). I felt like it was getting way more complicated than it should be.

Never realised state machines were so practical.

Avatar

Great episode.
I'm new to rails and so happy I subscribed.

Avatar

How can I use it in production? which option must I pass?
Thanks.

Avatar

Have you had any luck with this? I've tried just replacing the load "db/schema.rb", but it blew up =/

Avatar

Fixed now (posting for anyone else reading this)

Avatar

Fixed now (posting for anyone else reading this)

Avatar

In the current Rails 4 beta, the :child_index option for fields_for doesn't work. Use :index instead.

ruby
fields = f.fields_for(association, new_object, index: id) do |builder|
Avatar

I also agree with Kevin. These walkthroughs are informative.

It is not that easy to trace through the source code just by reading it, so it is very helpful to see how Ryan navigates the code and what he focuses on in each class or method.

Avatar

One of my favorites is Katrina Owen's "Therapeutic Refactoring": http://www.youtube.com/watch?v=J4dlF0kcThQ

Avatar

Something I was bit by lately was the SIGHUP signal.

I put a long running rake task in the background, making sure to redirect stderr to stdout. But when I logged out of my terminal, rake received a SIGHUP and aborted my processes.

Probably should have executed this with Resque or DelayedJob.

Avatar

Hi Mark,

Thank your for your info!

I'm not sure if I understand correctly.
Can you give me an example how it works and how it should work?

In the meantime I'll give you an idea how to make www. subdomain by default. Let's suppose:
1. First you open page that has url - for example <a href="http://mark.lvh.me:3000/">Show Mark</a>). You click it and new page opens.
2. Then you click link http://www.lvh.me:3000/adam (page has full url path - <a href="http://www.lvh.me:3000/adam">Show Adam</a>)
3. New page opens and it has only paths for example <a href="/adam">Show Adam</a>. It doen't have html code like <a href="http://lvh.me:3000/adam">Show Adam</a> - I guess you gets full url in this point.

How I did it?
1. added line before_filter :check_url_for_www
2. defined method check_url_for_www
It looks like that:

ruby
  def check_url_for_www
    redirect_to request.protocol + "www." + request.host_with_port + request.fullpath 
      if !/^www/i.match(request.host) 
      and !DomainFormatValidator::check_numeric_domain(request.host)
      and allowed_subdomains?
      and !Rails.env.test?
end

There is used DomainFormatValidator::check_numeric_domain method in the :check_url_for_www:

ruby
def self.check_numeric_domain( host)
  /^(\d{1,3}\.){3}(\d{1,3})$/.match( host)
end

and allowed_subdomains? ApplicationHelper's method:

ruby
def allowed_subdomains?
  !request.domain.blank?
end

The reason is you can use numeric addresing like 127.0.0.1:3000 for opening your page. In this case we cannot add www. subdomain.
Besides we chec if domain is blank. If true the we do nothing.

It works fine on my local, development environment. I've never tested it in the poduction environment, but I'm going to do that very soon :)

I hope it is clear. If not let me know :)

Avatar

Great episode Ryan!
Could you tell us your thoughts about what to do when an app has too many models?
Do you think namespacing or subfolders are good ideas?
Thanks!

Avatar

Thanks for uploading this video, but how do I parse tab delimited instead of comma ?

Avatar

Methodfinder is great. So many times I run into this case!

Avatar

Made simple google sign-in work with omniauth-google-oauth2 via https://code.google.com/apis/console/

I guess there exists other gems if I have a business google app and only want people with gmail-accounts connected to my specific company to to be able to sign in. Will keep researching that and am thankful for suggestions.

Avatar

Wait, if you're gitignoring your application.yml file, how do you get around this in your application.rb?

config = YAML.load(File.read(File.expand_path('../application.yml', __FILE__)))

I'm getting this when I try to run on heroku:

No such file or directory - /app/config/application.yml
Avatar

I'm using rails 3 .2.8.

The generator is apparently not found:

rails g sorcery:install --model Account
Could not find generator sorcery:install

gem list | grep sorcery
sorcery (0.7.13, 0.6.0)

Has anyone experienced this?

Avatar

Hi!
I want to add "sign in with google" to my application. I already have Twitter and Facebook based on episode 235 "Devise and omniauth" and their implementations were fair and simple.

Is it the omniauth-google_oauth2 gem I should use if I want people to be able to login with their gmail-accounts? If so, where will I find the ['GOOGLE_KEY'] and ['GOOGLE_SECRET']?. Is it by visiting https://code.google.com/apis/console/ and creating an api and using "Client ID" and "Client secret" from there? Or do I have to create some google business app or something?

I mean with Twitter and Facebook I only had to go to their dev-pages and create an app and then it was ready to use.

Or is it an entirely other omniauth gem I should use if I want people to login with gmail/google-accounts?

regards!

Avatar

How do celluloid actors mix with rails, especially active record?

Avatar

No matter what I do I get the XMLHttpRequest cannot load https://3r_photos.s3.amazonaws.com/. Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin.

error. If I tweak the env vars to be wrong, I still get the same error. I have CORS set as indicated. Not sure how to proceed. Any ideas on how to debug this? I've tried deleting and recreating a bucket. Next up is deleting my AWS account I think.

Avatar

Failures:

1) PasswordResets emails user when requesting password reset
Failure/Error: click_button "Reset Password"
ActiveRecord::RecordInvalid:
Validation failed: Password is too short (minimum is 6 characters), Password confirmation can't be blank
# ./app/models/user.rb:57:in send_password_reset'
# ./app/controllers/password_resets_controller.rb:7:in
create'
# (eval):2:in click_button'
# ./spec/requests/password_resets_spec.rb:9:in
block (2 levels) in '

Finished in 14.17 seconds
167 examples, 1 failure

Failed examples:

rspec ./spec/requests/password_resets_spec.rb:4 # PasswordResets emails user when requesting password reset


On the model user I have the following validations needed for my test unit:
validates :password, length: { minimum: 6 }
validates :password_confirmation, presence: true


Any help how to get the test to pass?!

Avatar

Thank you so much. This really helped me out. So glad you made this podcast. :)

Avatar

Great episode. For those of you who want access to the additional twitter bootstrap alert message types in addition to success and error try the following code:

Change

ruby
<div class="alert alert-<%= name == :notice ? "success" : "error" %>"> 

to

ruby
<div class="alert alert-<%=(name == :notice && 'success' or name == :warning && 'warning' or name == :info && 'info' or 'error')%>">
Avatar

this worked for me. thanks. the system could not locate bundle.

Avatar

I completely agree with Kevin Webster, and I really appreciate Ryan's effort to talk about such an entangled subject in a short screencast like this one.

If he goes too fast, no one stops you from pausing the recording as much as needed.

thanks again Ryan for your execlent work

Avatar

It's been my experience that understanding the inner workings of frameworks is exceptionally valuable for figuring out why things aren't behaving the way you expect them to.

Avatar

I agree! Gary's Destroy All Software is awesome and a good compliment to RailsCasts. :)

I usually do not cover theory but try to focus more on practical solutions to common problems. This episode is more of the former - I may do more of these occasionally.

Avatar

This is due to the has_secure_password behavior. We could extract this into the Authentication class however I don't know if that tradeoff is worth it.

Avatar

Grails which is inspired by Rails and written in Groovy, explicitly accounts for service objects just as Ryan explains here. I think for a few methods here and there, the "concern" or module mix-in approach is fine. But for something more substantial, a service object is better. It is a judgment call really.

Avatar

When unit testing the Service Object I can easily stub the method find_by_username. However the where would required an ugly stub chain. If the API changes the where clause is more costly than the find_by_username.

Having said that, there maybe a day when find_by_username is deprecated like it's cousin, find_all_by_ in Rails 4 and I would regret that choice :-)

If working on a team and they wanted to move the method find_by_username to the User I would be be totally cool with that, perhaps using the ActiveRelation syntax to build the query.

I know some folks advocate even hide the all method within their model, for example:

ruby
class Post
  alias_method :all_posts, :all
end

Anyway, I hope that gives you some idea into my thought process behind that :-)

Avatar

Why does this file https://github.com/railscasts/373-zero-downtime-deployment/blob/master/blog-after/config/recipes/templates/nginx_unicorn.erb contain this twice:

if (-f $document_root/system/maintenance.html) {
return 503;
}
error_page 503 @maintenance;
location @maintenance {
rewrite ^(.*)$ /system/maintenance.html last;
break;
}

Avatar

Thanks for giving some samples to the recent Tweet-Stream about this topic.
Concerns let you group functionality - nice. But in the end it all ends up mixed into the consumers class (User). I know it's nice Ruby magic - and there might be reasons or use cases to use Concerns. But somehow I like the service approach more. It's more explicit, better testable and more OO style - less 'Ruby meta style'.

Avatar

Can you explain why find_by_user name is different than than the User.where example? I guess I don't understand why one should belong there and the other one is debatable...

Avatar

ActiveSupport Concern is nice way to extend some class with module mixins, but to keep my controllers clean I rather use kindergarten. It is more convenient way to deal with controllers cleanup. Kindergarten additionally use CanCan for easier authorization (no more Ability.rb) and some more useful features.

Avatar

I agree. But for me railscasts is more a "Hi, check this new gem and learn how to use it in 10 minutes" series. While Gary Bernhardt's screencasts is more like "So, you think you know how to do standard rails stuff, well let me blow your mind" Alert => mindblowing: burn your controllers. They both are great but for different reasons.

Just for fun wat

Avatar

Thank you for highlighting the use of Service Objects, it's a technique that I have adopted and felt has improved the codebase for the projects I have worked on. There's probably one piece of code I would push back down into the model:

ruby
User.where(@omniauth.slice(:provider, :uid)).first_or_initialize

This query method exposes the ActiveRecord Query API and I would rather have that encapsulated in the ActiveRecord model. find_by_username is debatable, but I typically let those slip.

Thoughts?

Avatar

This works excellent for Excel files.

But how do I import a csv file that have ";" as a column separator instead of the default value ","?

Avatar

+1 for destroyallsoftware

agree that is more complementing, though i would love to have more "true pro" episodes like this on railscasts!

Avatar

Try this:

ruby
validates_uniqueness_of :slug, scope: :parent_id
Avatar

I really like this approach. I hate when the models get to fat ("ball of methods"). Many times they have to deal with tings that should not concern them. I use the lib folder and add workers for the complex controllers. One advantage is that you can run tests isolated form rails and tests get really fast.

If you like to see more screencasts on refactoring, go to destroyallsoftware
We call it rails porn (Yes, it's really that good!)

Sorry, Ryan for promoting another paid rails screencast series here, but I think that it's more complementing than competing with you.

Avatar

This episode is great. There is something weird however : the class authentication is calling authenticate on the user class. I think password authentication should be handle by the authentication class

Avatar

check out smarter_csv for easy renaming of the headers to match your model.

Avatar

So after spending a bit of time looking at Active Model I realized that my main problem was with the persisted? method always being false (when your controller has new, and update methods like that of #217 this becomes a problem as it always thinks it is creating a new object rather then using the already created one) the solution I had for this was to use ids and change the persisted method to this:

persisted model method
  def persisted?
    !(self.id.nil?)
  end