I just wanted to quickly point out that you are putting the ".DS_Store" into the wrong .gitignore file, IMHO. You put it into the ToDo app's .gitignore file, but actually it's not specific to the ToDo app, it is specific to your development environment (MacOS X). So, it belongs in your systemwide .gitignore, not the project-specific one.
Your association validation error message pastie rocks!
Here's an enhancement to it that strips out the useless "is invalid" error messages so you're only left with the useful association validation messages:
I'd highly recommend staying away from braid for the time being. In my experience it's been very buggy and has out and out thrashed a particular project badly enough that I had to re-import it form SVN.
Piston has forthcoming git support, so I'll be waiting for that.
Do either of you, by any chance have any nested models? I have a few (e.g. Lookups::Country, Lookups::State, etc).
I've noticed that I only ever have problems on these models whereas other models that reference one another from within the models directory are done so with no problems.
I read somewhere about foxy fixtures not handling relationships between models where the :foreign_key parameter is used, but I'm not 100% sure.
For lack of experience and time, I haven't figured out a solution to the issue but I hope it sheds some light.
I have a question. In this example the items disappear from the list when they are marked as complete.
What if you want to display the complete list all the time, but the check_box default value is based on the values from the tasks.
For those getting the error on IE: 'Object doesn't support this property or method'. As you probably saw it is being caused by this line: 'this.up('.something').remove()'
I spent about 3 hours tracking down this bug and its occurring because the scriptaculous prototype library (which provides functions like up, down, remove, etc) doesn't work the same way in IE.
For details read the bottom of this page:
http://prototypejs.org/learn/extensions
I can't believe this isn't documented better?!? Clearly lots of people are using embedding their own javascript into RJS.
It seems you have to use the Element.extend(something) function or the shorthand version of it $('something') so get those DOM objects to use scriptaculous functions.
So you can write the above line of code like this:
'Element.extend(this).up($('.something')).remove()'
And it works in all browsers. This seems pretty ridiculous so if someone has a better solution to this please post it.
http_basic only works when running through curl with http://user@pass:localhost:3000/etc, not when running in Safari or Camino--I never get a window to enter the credentials, it just passes through, and then obviously creates the dreaded "nil" error when the @user can't be authenticated and found.
>>You should consider increasing >>the width of your website. >>almost everyone has a wide >>screen monitor these days, and >>on my monitor 2/3'rds of your >>site is white space.
I strongly disagree. What you don't see is the negative effect this has on those people who must stay with a 680x800 screen for reasons of poorer vision. Making the text wider requires us to continuously scroll left and right, which is really aggravating.
RE PJ's security comment and Ryan's response: I was wondering exactly how that security risk would be fixed. What does the session[:admin] = true replace?
A future screencast I'd love to see would be about how to do testing when you are using Restful Authentication. I'm missing something (I hope) because it seems to be a bear to do, and your sceencasts always help with those sort of problems.
Yes, sorry. I meant that that "git add ." is only needed the first time for new files and the following times (for existing files) should "git commit -a" be enough.
Martin, I think you are wrong about using "git add .". To add new files to repository (index) you need to use "git add ." before commit.
"git commit -a" only adds modified files that are already part of the repository, not new files. So after "git init", or every time you add new files you should use "git add ."
Another great screencast.
One thing, you dont need to use `git add .` if you commit using the -a option. It will automatically add all modified files to the commit.
Ryan, thank-you for this informative screen cast! I have been taking a slightly different approach with the code for saving child properties in the controller, but your approach is much cleaner. Thanks again.
Hi guys,
anyone has used a dynamic field text with pagination for display. I mean after adding N fields a pagination system starts working in order to keep everything ordered within the view.
Yeah, rails is making shorter and shorter. That's nice but I am wondering when we approach the border when one command will do everything:D.
Great cast as usually.
great tutorials man. I wanted to note quickly that when using restful_authentication you can add a simple administrator check by using your boolean in the user table method
and calling:
def admin?
if logged in?
current_user.admin?
else
false
end
end
then create a new before filter
def admin_required
admin? || access_denied
end
Thats a simple way to do it, but it allows you to filted certain actions by wether a user is an admin and other by just if they are loggedin or not.
I've hacked mine up a lot more but for simple sites I somethimes use this method.
hey buddy ... look am just trying to build a search form for the company i work for... now this is just the simplest of search forms i require.... just so that we can locate the site map and areas of this site... by typing the area code or name... i dont have any experience in this... do u know how i can download something like that or create it in a very basic format yet effictive... please get back to me as soon as possible.... i would appreciate ur help
I played with the "error" that you showed in your screencast, but the expression works now fine in Rails (I should say in ActiveSupport); doing the calculation now (it is March 6 as I write):
Date.today + 10.days -> Sun, 16 Mar 2008
I was stunned, and I used the debugger to step through in ActiveSupport; it's a long story, but basically it does not evaluate inmediately '10.days'.
Rather it ends up with an array of "parts" [[:days, 10]], that allows to do the right thing when finally doing the sum.
I know that your point was to show the debugger, but I wanted to let you know that perhaps the example should be updated, if you ever have the chance.
[By the way, as many others, I love your screencasts]
Thanks so much for all these screencasts. I've pretty much downloaded them all now, and refer to them a LOT whenever I forget things. This is an excellent resource!
Great screencast again! I really like the way you were using script/console that you can see the exact http request on the server side. Can you kindly tell me how to setup it?
@andy
I think it's only possible to access one nest of resources in one model, i think it could get complicated when you're changing self.site at runtime. Anyway, for myself, I was able to run ActiveResources through nested resources, all I've done was:
class Project < ActiveResource::Base
self.site = http://localhost:3000/users/:user_id
end
If you like to call a find method you have to do it like this:
Project.find(:all, :params => {:user_id => 5})
For sure your REST Service has to support this kind of request.
I just tested out the restful authentication and noticed the Rails log had the password param unencrypted: "password"=>"abcd1234." I think I've seen documentation about hiding that param in the log file. But, is it also sent in clear text across the wire from browser to server?
i think what would have been helpful after having done all this setup is to show how to test if the setup is correct via script/console.
the way this is presented, it seems to asume that you have all this work done on having users, and what i would want to do first is test if the setup was correct. are there a few commands that will get to that?
also, in some cases i have seen things defined as this:
Ok I've solved it.
You got to modify your js.erb file, so it won't observe since you can't get the elements with the same ID from the js file.
So in partial with countries and states do:
f.collection_select(:country, Country.find(:all), :id, :name, {:include_blank => true }, :onchange => "collectionSelected(this);")
And your js.erb will look like:
// array generation
function collectionSelected(e) {
country_id = e.getValue();
options = e.next(1).options;
options.length = 1;
states.each(function(model) {
if (state[0] == country_id) {
options[options.length] = new Option(state[1], state[2]);
}
});
}
How can it work with your 3-part complex forms casts?
When you add new task and each task on page will have those related dropdown how you refer to them?
When you add new task the div that you create in "simplify_views_for_rails_2.0" has id="new_task".
Each has id="new_task" and it is mark-up error.
Can you figure that out, cause that will be helpful!:)
ps. great railscasts! continue!
First of all, happy birthday, I've been watching since day one (actually day 14, since I heard of you in RubyInside which posted the announcement on March 19th :)) and even after two years of using rails I learn a few little things here and there every week -- particularly those handy textmate shortcuts! :D
THANK YOU!
Second, and I'm just nitpicking, so don't mind me ;), the discontinue action should conceptually be a DELETE, not a PUT. By discontinuing the product you're "removing" it from the cloud, even if you aren't deleting it from the database :)
@Ryan Townsend:
In edge rails you don't have to override self.site anymore, you can use self.user and self.password :)
@andy, good question. I usually don't use nested resources, but I know many do so I looked into it while planning this episode. Unfortunately I wasn't able to find a solution. There are some examples where you set it in the "site" string as shown here:
http://whynotwiki.com/ActiveResource
But I was not able to get this to work. If anyone knows the solution please reply.
@vince, from my understanding the salt doesn't have anything to do with decrypting. A salt is just a random string of characters appended to the password before hashing. This helps prevent dictionary attacks if someone is trying to break the hash. I'm no expert on ecryption, so take this with a grain of salt (pun intended).
First of all thanks for casts.
All of them really helpful.
Maybe you can answer my question.
Made several projects with restful_authentication but still didn't figure out bonuses of salt in model. I though salt is required for for decrypting but using sha we don't have such option.
@Tim, yep, actually content_for is just setting an instance variable in the background. I believe it's called @content_for_title (or whatever you pass to the method). You can reference this instance variable directly if you need, or just stick with yield(:title) which basically does the same thing.
Hi,
I just wanted to quickly point out that you are putting the ".DS_Store" into the wrong .gitignore file, IMHO. You put it into the ToDo app's .gitignore file, but actually it's not specific to the ToDo app, it is specific to your development environment (MacOS X). So, it belongs in your systemwide .gitignore, not the project-specific one.
jwm
@chrisff
Your association validation error message pastie rocks!
Here's an enhancement to it that strips out the useless "is invalid" error messages so you're only left with the useful association validation messages:
http://pastie.caboo.se/165073
I'd highly recommend staying away from braid for the time being. In my experience it's been very buggy and has out and out thrashed a particular project badly enough that I had to re-import it form SVN.
Piston has forthcoming git support, so I'll be waiting for that.
Adam, Tellman
Do either of you, by any chance have any nested models? I have a few (e.g. Lookups::Country, Lookups::State, etc).
I've noticed that I only ever have problems on these models whereas other models that reference one another from within the models directory are done so with no problems.
I read somewhere about foxy fixtures not handling relationships between models where the :foreign_key parameter is used, but I'm not 100% sure.
For lack of experience and time, I haven't figured out a solution to the issue but I hope it sheds some light.
I have a question. In this example the items disappear from the list when they are marked as complete.
What if you want to display the complete list all the time, but the check_box default value is based on the values from the tasks.
For those getting the error on IE: 'Object doesn't support this property or method'. As you probably saw it is being caused by this line: 'this.up('.something').remove()'
I spent about 3 hours tracking down this bug and its occurring because the scriptaculous prototype library (which provides functions like up, down, remove, etc) doesn't work the same way in IE.
For details read the bottom of this page:
http://prototypejs.org/learn/extensions
I can't believe this isn't documented better?!? Clearly lots of people are using embedding their own javascript into RJS.
It seems you have to use the Element.extend(something) function or the shorthand version of it $('something') so get those DOM objects to use scriptaculous functions.
So you can write the above line of code like this:
'Element.extend(this).up($('.something')).remove()'
And it works in all browsers. This seems pretty ridiculous so if someone has a better solution to this please post it.
http_basic only works when running through curl with http://user@pass:localhost:3000/etc, not when running in Safari or Camino--I never get a window to enter the credentials, it just passes through, and then obviously creates the dreaded "nil" error when the @user can't be authenticated and found.
>>You should consider increasing >>the width of your website. >>almost everyone has a wide >>screen monitor these days, and >>on my monitor 2/3'rds of your >>site is white space.
I strongly disagree. What you don't see is the negative effect this has on those people who must stay with a 680x800 screen for reasons of poorer vision. Making the text wider requires us to continuously scroll left and right, which is really aggravating.
Prior to getting my new mac, I was on windows and was playing around with a windows port of Git called 'Git Bash'
http://code.google.com/p/msysgit/
and a little installation walkthrough:
http://kerneltrap.org/Linux/Git_on_Windows
--Good luck guys!
@Gav: something/**/* will go down all the subdirectories of 'something' and select all the files inside.
@Ryan, Pete: shouldn't you also ignore the schema.rb?
In my personal experience, git is the best thing that happened to my workflow since rails :)
Great episode -- this was really helpful.
RE PJ's security comment and Ryan's response: I was wondering exactly how that security risk would be fixed. What does the session[:admin] = true replace?
I feel a little silly asking, but what does ** mean?
Ryan and Pete Yandell (in a comment) used it in their .gitignore files
tmp/**/*
Thanks
Hello Ryan, I have the same question as Ben. Could you spend some thoughts on it please? Thanks!
@Senthil:
Better Git support is built into msysGit:
http://code.google.com/p/msysgit/
Still, lacks git-svn support due perl bindings, but is usable :)
In any case, the steeped learning curve of Git (ala: the bad UI design it has) make me stay away from it and keep using bazaar as SCM.
A future screencast I'd love to see would be about how to do testing when you are using Restful Authentication. I'm missing something (I hope) because it seems to be a bear to do, and your sceencasts always help with those sort of problems.
Yes, sorry. I meant that that "git add ." is only needed the first time for new files and the following times (for existing files) should "git commit -a" be enough.
Martin, I think you are wrong about using "git add .". To add new files to repository (index) you need to use "git add ." before commit.
"git commit -a" only adds modified files that are already part of the repository, not new files. So after "git init", or every time you add new files you should use "git add ."
Another great screencast.
One thing, you dont need to use `git add .` if you commit using the -a option. It will automatically add all modified files to the commit.
Thanks Ryan, another great screencast.
I'd been holding back for the same reason Matt gave. The try-something-new temptation is strong though... so time to give it a try me thinks!
I use the following little "git-rails" script to take a new Rails project and initialise it as a git repository.
#!/bin/sh
git init
cat <<EOF > .gitignore
.DS_Store
log/*.log
tmp/**/*
db/*.sqlite3
coverage
doc/app/*
EOF
find . -type d -empty -exec touch {}/.gitignore \;
git add .
git commit -a -m "Initial import."
Hearing good things about GIT for quiet some time but, lack of windows support is holding us back.
till we get some native binaries(not cygwin), we would remain with subversion.
Git does look pretty good, but so far subversion has done everything I have needed it to.
heh i was scourging the entire internets for this exact screencast last night. thanks!
Ryan, thank-you for this informative screen cast! I have been taking a slightly different approach with the code for saving child properties in the controller, but your approach is much cleaner. Thanks again.
Hi guys,
anyone has used a dynamic field text with pagination for display. I mean after adding N fields a pagination system starts working in order to keep everything ordered within the view.
THANKS.
I found in a german forum that you only need to add this to the application.rhtml file:
<%= javascript_include_tag :defaults %>
And it works!!
Hi Harrel,
I get an rjs error too using rails 2.0. Can anybody help? Mine says ReferenceError: Insertion is not defined
Yeah, rails is making shorter and shorter. That's nice but I am wondering when we approach the border when one command will do everything:D.
Great cast as usually.
Steve,
add something like this to your application.rb file:
filter_parameter_logging :password, :password_confirmation
great tutorials man. I wanted to note quickly that when using restful_authentication you can add a simple administrator check by using your boolean in the user table method
and calling:
def admin?
if logged in?
current_user.admin?
else
false
end
end
then create a new before filter
def admin_required
admin? || access_denied
end
Thats a simple way to do it, but it allows you to filted certain actions by wether a user is an admin and other by just if they are loggedin or not.
I've hacked mine up a lot more but for simple sites I somethimes use this method.
Great screencasts man.
hey buddy ... look am just trying to build a search form for the company i work for... now this is just the simplest of search forms i require.... just so that we can locate the site map and areas of this site... by typing the area code or name... i dont have any experience in this... do u know how i can download something like that or create it in a very basic format yet effictive... please get back to me as soon as possible.... i would appreciate ur help
Hi, Ryan,
I played with the "error" that you showed in your screencast, but the expression works now fine in Rails (I should say in ActiveSupport); doing the calculation now (it is March 6 as I write):
Date.today + 10.days -> Sun, 16 Mar 2008
I was stunned, and I used the debugger to step through in ActiveSupport; it's a long story, but basically it does not evaluate inmediately '10.days'.
Rather it ends up with an array of "parts" [[:days, 10]], that allows to do the right thing when finally doing the sum.
I know that your point was to show the debugger, but I wanted to let you know that perhaps the example should be updated, if you ever have the chance.
[By the way, as many others, I love your screencasts]
Raul
Thanks so much for all these screencasts. I've pretty much downloaded them all now, and refer to them a LOT whenever I forget things. This is an excellent resource!
Great screencast again! I really like the way you were using script/console that you can see the exact http request on the server side. Can you kindly tell me how to setup it?
Thanks again.
@andy
I think it's only possible to access one nest of resources in one model, i think it could get complicated when you're changing self.site at runtime. Anyway, for myself, I was able to run ActiveResources through nested resources, all I've done was:
class Project < ActiveResource::Base
self.site = http://localhost:3000/users/:user_id
end
If you like to call a find method you have to do it like this:
Project.find(:all, :params => {:user_id => 5})
For sure your REST Service has to support this kind of request.
Thank you for this video.
Cool!! Thanks a lot.
Ryan,
Thanks for the railscasts! They're great.
I just tested out the restful authentication and noticed the Rails log had the password param unencrypted: "password"=>"abcd1234." I think I've seen documentation about hiding that param in the log file. But, is it also sent in clear text across the wire from browser to server?
i think what would have been helpful after having done all this setup is to show how to test if the setup is correct via script/console.
the way this is presented, it seems to asume that you have all this work done on having users, and what i would want to do first is test if the setup was correct. are there a few commands that will get to that?
also, in some cases i have seen things defined as this:
ActionMailer::Base.smtp_settings = {
:address => "your smtp server",
:port => smtp-port,
:domain => 'your domain'
}
verses the way that you did it here... is this a newer way to do setup?
Ok I've solved it.
You got to modify your js.erb file, so it won't observe since you can't get the elements with the same ID from the js file.
So in partial with countries and states do:
f.collection_select(:country, Country.find(:all), :id, :name, {:include_blank => true }, :onchange => "collectionSelected(this);")
And your js.erb will look like:
// array generation
function collectionSelected(e) {
country_id = e.getValue();
options = e.next(1).options;
options.length = 1;
states.each(function(model) {
if (state[0] == country_id) {
options[options.length] = new Option(state[1], state[2]);
}
});
}
and thats it :)
Add
require "openid"
at the top of your controller
Regards,
Amit
How can it work with your 3-part complex forms casts?
When you add new task and each task on page will have those related dropdown how you refer to them?
When you add new task the div that you create in "simplify_views_for_rails_2.0" has id="new_task".
Each has id="new_task" and it is mark-up error.
Can you figure that out, cause that will be helpful!:)
ps. great railscasts! continue!
First of all, happy birthday, I've been watching since day one (actually day 14, since I heard of you in RubyInside which posted the announcement on March 19th :)) and even after two years of using rails I learn a few little things here and there every week -- particularly those handy textmate shortcuts! :D
THANK YOU!
Second, and I'm just nitpicking, so don't mind me ;), the discontinue action should conceptually be a DELETE, not a PUT. By discontinuing the product you're "removing" it from the cloud, even if you aren't deleting it from the database :)
@Ryan Townsend:
In edge rails you don't have to override self.site anymore, you can use self.user and self.password :)
http://blog.codefront.net/2008/02/27/living-on-the-edge-of-rails-9-the-sleeper-edition/
Great screencasts - could you please do one on making drag and drop widgets?
@andy, good question. I usually don't use nested resources, but I know many do so I looked into it while planning this episode. Unfortunately I wasn't able to find a solution. There are some examples where you set it in the "site" string as shown here:
http://whynotwiki.com/ActiveResource
But I was not able to get this to work. If anyone knows the solution please reply.
@vince, from my understanding the salt doesn't have anything to do with decrypting. A salt is just a random string of characters appended to the password before hashing. This helps prevent dictionary attacks if someone is trying to break the hash. I'm no expert on ecryption, so take this with a grain of salt (pun intended).
Ryan - how would you use ARes to access a nested resource, like:
/admin/users #namespace route
/users/posts #nested route
Thanks for these screencasts!!!
Hey Ryan,
First of all thanks for casts.
All of them really helpful.
Maybe you can answer my question.
Made several projects with restful_authentication but still didn't figure out bonuses of salt in model. I though salt is required for for decrypting but using sha we don't have such option.
Thanks,
Vince
Hi Ryan, thx for all these great videos. I wonder if you can upload pictures to the database in this way?
@Tim, yep, actually content_for is just setting an instance variable in the background. I believe it's called @content_for_title (or whatever you pass to the method). You can reference this instance variable directly if you need, or just stick with yield(:title) which basically does the same thing.