This code repeats 3 times. I've made press_enter method:
ruby
defpress_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 textCapistrano::Configuration.default_io_proc.call( ch, stream, data)
endend
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:truedo |ch, stream, data|
press_enter( ch, stream, data)
end
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?!
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!
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.
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.
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.
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
defcheck_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
defself.check_numeric_domain( host)
/^(\d{1,3}\.){3}(\d{1,3})$/.match( host)
end
and allowed_subdomains? ApplicationHelper's method:
ruby
defallowed_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 :)
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!
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.
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?
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.
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:increate'
# (eval):2:in click_button'
# ./spec/requests/password_resets_spec.rb:9:inblock (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
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:
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.
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.
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.
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.
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.
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
classPost
alias_method :all_posts, :allend
Anyway, I hope that gives you some idea into my thought process behind that :-)
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'.
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...
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.
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.
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:
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.
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.
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
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:
This code repeats 3 times. I've made
press_enter
method: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:
I have the same concern, is something about performance or better practices? Anyone?
Thanks for the episode!
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?!
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...?
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.
Great episode.
I'm new to rails and so happy I subscribed.
How can I use it in production? which option must I pass?
Thanks.
Have you had any luck with this? I've tried just replacing the load "db/schema.rb", but it blew up =/
Fixed now (posting for anyone else reading this)
Fixed now (posting for anyone else reading this)
In the current Rails 4 beta, the
:child_index
option forfields_for
doesn't work. Use:index
instead.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.
One of my favorites is Katrina Owen's "Therapeutic Refactoring": http://www.youtube.com/watch?v=J4dlF0kcThQ
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
tostdout
. But when I logged out of my terminal, rake received aSIGHUP
and aborted my processes.Probably should have executed this with Resque or DelayedJob.
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:
There is used
DomainFormatValidator::check_numeric_domain
method in the:check_url_for_www
:and
allowed_subdomains?
ApplicationHelper's method: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 :)
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!
Thanks for uploading this video, but how do I parse tab delimited instead of comma ?
Methodfinder is great. So many times I run into this case!
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.
Wait, if you're gitignoring your application.yml file, how do you get around this in your application.rb?
I'm getting this when I try to run on heroku:
I'm using rails 3 .2.8.
The generator is apparently not found:
Has anyone experienced this?
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!
How do celluloid actors mix with rails, especially active record?
good
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.
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'
create'# ./app/controllers/password_resets_controller.rb:7:in
# (eval):2:in
click_button'
block (2 levels) in '# ./spec/requests/password_resets_spec.rb:9: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?!
Thank you so much. This really helped me out. So glad you made this podcast. :)
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
to
+1
this worked for me. thanks. the system could not locate bundle.
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
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.
These are also good on the subject of refactoring
http://www.confreaks.com/videos/1115-gogaruco2012-go-ahead-make-a-mess
http://www.confreaks.com/videos/1233-aloharuby2012-refactoring-from-good-to-great
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.
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.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.
When unit testing the Service Object I can easily stub the method
find_by_username
. However thewhere
would required an ugly stub chain. If the API changes thewhere
clause is more costly than thefind_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:Anyway, I hope that gives you some idea into my thought process behind that :-)
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;
}
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'.
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...
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.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
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:
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?
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 ","?
+1 for destroyallsoftware
agree that is more complementing, though i would love to have more "true pro" episodes like this on railscasts!
Try this:
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.
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
check out smarter_csv for easy renaming of the headers to match your model.
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: