Wow, just had a look at Interface Kit (InK), it's really nice. I think I prefer it over Twitter Bootstrap. I looked at Zurb Foundation quite a while back, might need to re-evaluate it too. Thanks for sharing!
This is very appropriate for apps backed by web services where the app may not have a direct database connection. I'm currently working on such an app and the API serves JSON, so building form objects that are custom for the purpose is definitely the way to go. Thanks for showing us this technique.
Can you post your code? Are you using HABTM or HMT? Have you created a join table? You will definitely need attr_accessible :skill_ids for Rails 2/3, or params.require(:model).permit(:skill_ids) in the controller if you're using Rails 4. I'm happy to help if you can share your code. Maybe add it to a gist and then reference it in a reply.
Ok I understand. I'm not sure I'd want to back out of the transaction because the activity tracking failed though... the recipe saved, the notification failed - seems like a secondary transaction to me, failure of which would be logged, retried and possibly even pushed onto a queue or other out-of-band process.
Unless you're explicitly handling particular formats (for example you have a respond_to block in your action that only handles the html format), then Rails will automatically look for a view that matches the incoming requested format. So if you have the following in your controller:
ruby
defnew@post = Post.new
end
And the incoming request format is js, Rails will look for a matching js view to render (ie. new.js.erb). If the request format is html, then Rails will look for a matching html view to render (ie. new.html.erb).
I've played a lot with OmniAuth Identity, and in the end for the little it provides, I don't think it's worthwhile.
I found that after having to override it's views, and having to add password recovery, authentication redirection and session remember me functionality myself, I may as well just use Rails 3's has_secure_password myself. I've ditched OmniAuth Identity in favor of Rails built-in has_secure_password, and I'm much happier and find it's much cleaner and nothing is abstracted away.
Why would you make the :password_digest accessible? The :password and :password_confirmation are the only password attributes that should be accessible. If you open up the :password_digest you just compromised your security model.
namespace :imagemagickdo
desc "Install the latest release of ImageMagick and the MagickWand Dev Library"
task :install, roles::appdo
run "#{sudo} apt-get -y update"
run "#{sudo} apt-get -y install imagemagick libmagickwand-dev"end
after "deploy:install", "imagemagick:install"end
I would have liked to see how you handle concatenating multiple fields for the date/time/zone... rails date and time tag helpers are quite clumsy for users to operate. I tend to use text fields for both date and time and a select for time zone, with javascript popups for input selection. I hate the code in my model that puts this all together into a single database datetime column. Do you have a preferred method of handling this type of situation?
Yeah I understand, and I'm not knocking Sidekiq. I've been using sidekiq since it's early days, and in a very big project. It performs flawlessly. I was just expressing a sentiment that's all... I would rather just have one database to install/maintain/monitor. Kudos to you for creating and sharing sidekiq.
I almost fell over too not knowing this. The fact that Rails is reserving a connection I guess part of the 'magic'. I'm wondering now if there's something out I can use to tell Rails not to reserve a connection, or to make controllers explicitly define whether they require a connection...
This is probably a dumb question but, does using Globalize3 mean our original table (say Articles) now has empty columns for attributes that are translated and stored in the translation table?
Wow, what an incredibly informative episode. I learned quite a few things - especially about my troubles getting my remote production envronment to play well with bundler. Thanks!
Yes I do have the environment loaded as you've suggested, that's why I don't understand why this doesn't work. I'm going to try bundle exec to run the rake task when I get back to that project and see if that helps at all.
I've also tried with and without attr_accessible, makes no difference, still get the error.
Is it just me or can we not access the new key/value store attribute in a rake task? I'm trying to set values of some keys in a kv store attribute, and I'm getting an unknown attribute error.
However, I have no such issue when I access or try to set the same attributes via the console.
I also tried to set values in the class initialize method, which works fine in Rails and the console. I get the same error when the class in initialized in a rake task.
I ran into the same issue, I resolved it by adding an ignore parameter on the tree method.
I have a Family model (for a product):
ruby
classFamily < ActiveRecord::Base
has_ancestry
defself.tree(ignore=nil)
ancestry_options(Family.scoped.arrange(:order => 'name'), ignore) { |i|
"#{'-' * i.depth}#{i.name}"
}
enddefself.ancestry_options(items, ignore)
result = []
items.map do |item, sub_items|
result << [yield(item), item.id] unless item.id == ignore
result += ancestry_options(sub_items, ignore) { |i|
"#{'-' * i.depth}#{i.name}"
}
end
result
endend
In my view partial, I use the following to render a select tag - obviously the id_to_ignore is the family_id of the family I want to exclude in my select tag:
ruby
# _product.html.erb (I use SimpleForm)
<%= f.association :family, label: t(".family"), collection: Family.tree(id_to_ignore), include_blank: false, input_html: { multiple: false } %>
It's amazing how much I learned from this episode, for instance, I had no idea why we were submitting the hidden field for checkboxes; I also totally forgot about the dom_id method, and have been hacking id's together. I think I have some refactoring to do.
Thanks Ryan for an awesome year of Railcasts. Happy Holidays and all the best for the New Year!
Thanks for summarizing for us @Daniel, I was going to ask the same question. I've been struggling with which engine to use for a production app. I watched this screencast with a bit of an attitude - oh crap another search engine. But after reading your reasoning I think I might give ES a go now, rather than the others. You've managed to turn me around.
There's nothing wrong with that approach either. I think it depends on the specific use case.
I have both strategies in one of my apps. Visitor searches on the public site are not stored, but admin searches in the marketing module are because they provide the criteria for targeting a segment of a marketing list which is then used by a backend job to send emails. Since the list changes as subscribers come and go, having the list based on search criteria is essential.
So this type of advanced search definitely has it's use case. Thanks for the revision Ryan.
Mercury-rails has a dependencies on Formtastic and Paperclip, which I find personally annoying. I tend to use Simpleform and Carrierwave myself, so I'm working on a fork that will remove these dependencies and employ a concept of providers for image-handling. Not sure what to do about Formtastic. It's almost syntactically compatible with Simpleform, but it's use is quite limited. I think a way to delegate options form building to your application would be better, then you'd be free to handle it however you like. All in all, Mercury is awesome, and I'm using it myself. Kudos to Jeremy for sharing it.
Hmmm, some good points made in these comments. And I have to say I'm leaning towards Sergey Kuleshov's comment. This is a very cool screencast, but I'm not sure I'd go this far in a production project.
I like that you're showing us Coffeescript usage too Ryan, it's lowering the barrier for me, but I've got to say, I still prefer straight Javascript. I still find Coffeescript very hard to read. Ultimately, I think I'd love to be able to write my Javascript in Ruby.
The similarity of Ruby's new hash syntax is bringing the two closer, and this is something I adopted only this week. Yeah, I know... slow on the uptake.
I agree with Doug Puchalski, I've been using Active Admin for some time now, and also found myself fighting with it constantly to get it to do things I wanted. I have several blog posts dedicated to some workarounds I found.
Active Admin looks beautiful and works great if you don't want to push it too far. I recently dropped Active Admin in favor of a manual hand-coded version for several reasons. I found the release cycle very slow. I also didn't like the dependence on Formtastic and Devise.
Kudos to the guys who put it together though, it really is a nice gem. It just doesn't fit a project that needs a lot of customizing.
@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
classPasswordResetsController < ApplicationControllerdefnewenddefcreate
user = User.find_by_email(params[:email])
user.send_password_reset if user
redirect_to root_url, :notice => "Password reset instructions sent by email."enddefedit@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."endenddefupdate@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 :editendendend
And thanks for showing us this, I've now ditched Devise and feel cleansed.
As a side note Ryan, I've noticed our avatars are being cached here at Railscasts. I updated my account at Github months ago and I'm seeing old info here, is there a way we can force a refresh on our profile here at Railscasts?
I know I can edit my profile, but I can't change my Github account.
Thanks Ryan for a great intro to CoffeeScript - I've been eagerly anticipating an episode on this this.
And thank you to Trevor Burnham for your comments. I can see now why I should learn CoffeeScript. It didn't quite click that I'd be moving any syntax errors into compile time until I read your comment. That's a big plus in my opinion. I look forward to buying and reading your book.
As a side note, I've just taken a fresh look at HAML because I started playing around with ActiveAdmin. I must say I really must have been in a bad mood the last time I looked at it because now it really does seem appealing. I will have to play with it a little more too I think (even though it's not a default in the Rails stack)!
If nothing else Rails is teaching me to be more open-minded.
Awesome episode Ryan. I needed this in an existing Rails 2.3.8 project, so I made a few changes to suit.
If anyone is interested, my fork is at: https://github.com/MeetDom/railscasts-episodes/tree/rails238/episode-255
Includes the sqlite3 db with products and has fixes to deal with undoing a create which was throwing an ActiveRecord::RecordNotFound error. I substituted @template for view_context since it's not available in until Rails 3.
Hope this helps someone else still using Rails 2.3.8.
Wow, just had a look at Interface Kit (InK), it's really nice. I think I prefer it over Twitter Bootstrap. I looked at Zurb Foundation quite a while back, might need to re-evaluate it too. Thanks for sharing!
This is very appropriate for apps backed by web services where the app may not have a direct database connection. I'm currently working on such an app and the API serves JSON, so building form objects that are custom for the purpose is definitely the way to go. Thanks for showing us this technique.
Anyone noticed strange artifacts between 5:13 and 5:50 mins when Ryan is explaining the Rack request variables (iTunes MP4 version)?
Can you post your code? Are you using HABTM or HMT? Have you created a join table? You will definitely need
attr_accessible :skill_ids
for Rails 2/3, orparams.require(:model).permit(:skill_ids)
in the controller if you're using Rails 4. I'm happy to help if you can share your code. Maybe add it to a gist and then reference it in a reply.I agree. They are they a good reminder for optimization techniques and what has been deprecated as we move move into new Rails versions.
+1
Ok I understand. I'm not sure I'd want to back out of the transaction because the activity tracking failed though... the recipe saved, the notification failed - seems like a secondary transaction to me, failure of which would be logged, retried and possibly even pushed onto a queue or other out-of-band process.
The
track_activity
method is only called if the@recipe.save
succeeds in the episode.Excellent cast, I can definitely see how the jQuery soup I currently have can be moved into AngularJS. And 404 not found - very funny.
@chewmanfoo, I'm not sure but I'm guessing you're missing the css style and instantiating the behavior:
And then instantiate add the behavior to elements with the
.chzn-select
css class:This is excellent - it removes so much of the hassle. Thanks for sharing, I'm definitely going to be using this.
Unless you're explicitly handling particular formats (for example you have a respond_to block in your action that only handles the html format), then Rails will automatically look for a view that matches the incoming requested format. So if you have the following in your controller:
And the incoming request format is
js
, Rails will look for a matching js view to render (ie. new.js.erb). If the request format ishtml
, then Rails will look for a matching html view to render (ie. new.html.erb).http://guides.rubyonrails.org/layouts_and_rendering.html and http://guides.rubyonrails.org/action_controller_overview.html are good resources for understanding ActionController and ActionView.
I've played a lot with OmniAuth Identity, and in the end for the little it provides, I don't think it's worthwhile.
I found that after having to override it's views, and having to add password recovery, authentication redirection and session remember me functionality myself, I may as well just use Rails 3's has_secure_password myself. I've ditched OmniAuth Identity in favor of Rails built-in has_secure_password, and I'm much happier and find it's much cleaner and nothing is abstracted away.
Why would you make the
:password_digest
accessible? The:password
and:password_confirmation
are the only password attributes that should be accessible. If you open up the:password_digest
you just compromised your security model.This worked for me on Ubuntu 12.04:
Thank you, I was wondering why the group didn't exist.
I would have liked to see how you handle concatenating multiple fields for the date/time/zone... rails date and time tag helpers are quite clumsy for users to operate. I tend to use text fields for both date and time and a select for time zone, with javascript popups for input selection. I hate the code in my model that puts this all together into a single database datetime column. Do you have a preferred method of handling this type of situation?
Yeah I understand, and I'm not knocking Sidekiq. I've been using sidekiq since it's early days, and in a very big project. It performs flawlessly. I was just expressing a sentiment that's all... I would rather just have one database to install/maintain/monitor. Kudos to you for creating and sharing sidekiq.
Would be nice if Sidekiq could use PG instead of Redis.
My head is spinning a little... thinking of all the things that could be done with this. Thanks - excellent episode.
Thanks for the heads up!
I almost fell over too not knowing this. The fact that Rails is reserving a connection I guess part of the 'magic'. I'm wondering now if there's something out I can use to tell Rails not to reserve a connection, or to make controllers explicitly define whether they require a connection...
This is probably a dumb question but, does using Globalize3 mean our original table (say Articles) now has empty columns for attributes that are translated and stored in the translation table?
This is interesting, I'll have to do some research. Thanks for sharing.
Nice!
This is really excellent stuff - definitely going to make use of this!
+1
And versioning!
Nice to see how to implement Hstore in rails views. Thanks Ryan.
Nice introduction to QC - thanks heaps. What's with that video poster though? ;-)
I'm definitely considering the jump to Postgres, it would be really nice if there was a PG engine for Faye.
Wow, what an incredibly informative episode. I learned quite a few things - especially about my troubles getting my remote production envronment to play well with bundler. Thanks!
Yes I do have the environment loaded as you've suggested, that's why I don't understand why this doesn't work. I'm going to try
bundle exec
to run the rake task when I get back to that project and see if that helps at all.I've also tried with and without
attr_accessible
, makes no difference, still get the error.Is it just me or can we not access the new key/value store attribute in a rake task? I'm trying to set values of some keys in a kv store attribute, and I'm getting an unknown attribute error.
However, I have no such issue when I access or try to set the same attributes via the console.
I also tried to set values in the class initialize method, which works fine in Rails and the console. I get the same error when the class in initialized in a rake task.
Any ideas?
Do you have a _message.html.erb partial in your app/views/messages directory?
I ran into the same issue, I resolved it by adding an ignore parameter on the tree method.
I have a Family model (for a product):
In my view partial, I use the following to render a select tag - obviously the id_to_ignore is the family_id of the family I want to exclude in my select tag:
I hope this helps.
It's amazing how much I learned from this episode, for instance, I had no idea why we were submitting the hidden field for checkboxes; I also totally forgot about the dom_id method, and have been hacking id's together. I think I have some refactoring to do.
Thanks Ryan for an awesome year of Railcasts. Happy Holidays and all the best for the New Year!
Excellent episode Ryan, I really love the fallback functionality remaining intact. Definitely going to use this.
Thanks for summarizing for us @Daniel, I was going to ask the same question. I've been struggling with which engine to use for a production app. I watched this screencast with a bit of an attitude - oh crap another search engine. But after reading your reasoning I think I might give ES a go now, rather than the others. You've managed to turn me around.
There's nothing wrong with that approach either. I think it depends on the specific use case.
I have both strategies in one of my apps. Visitor searches on the public site are not stored, but admin searches in the marketing module are because they provide the criteria for targeting a segment of a marketing list which is then used by a backend job to send emails. Since the list changes as subscribers come and go, having the list based on search criteria is essential.
So this type of advanced search definitely has it's use case. Thanks for the revision Ryan.
Mercury-rails has a dependencies on Formtastic and Paperclip, which I find personally annoying. I tend to use Simpleform and Carrierwave myself, so I'm working on a fork that will remove these dependencies and employ a concept of providers for image-handling. Not sure what to do about Formtastic. It's almost syntactically compatible with Simpleform, but it's use is quite limited. I think a way to delegate options form building to your application would be better, then you'd be free to handle it however you like. All in all, Mercury is awesome, and I'm using it myself. Kudos to Jeremy for sharing it.
Hmmm, some good points made in these comments. And I have to say I'm leaning towards Sergey Kuleshov's comment. This is a very cool screencast, but I'm not sure I'd go this far in a production project.
I like that you're showing us Coffeescript usage too Ryan, it's lowering the barrier for me, but I've got to say, I still prefer straight Javascript. I still find Coffeescript very hard to read. Ultimately, I think I'd love to be able to write my Javascript in Ruby.
The similarity of Ruby's new hash syntax is bringing the two closer, and this is something I adopted only this week. Yeah, I know... slow on the uptake.
Your Github link does not work.
I agree with Doug Puchalski, I've been using Active Admin for some time now, and also found myself fighting with it constantly to get it to do things I wanted. I have several blog posts dedicated to some workarounds I found.
Active Admin looks beautiful and works great if you don't want to push it too far. I recently dropped Active Admin in favor of a manual hand-coded version for several reasons. I found the release cycle very slow. I also didn't like the dependence on Formtastic and Devise.
Kudos to the guys who put it together though, it really is a nice gem. It just doesn't fit a project that needs a lot of customizing.
Great episode as usual, but I'm getting sick of authentication. Not that I'm unappreciative, I do watch your episodes religiously each week.
Maybe an episode on Mercury, with carrier wave uploads and snippets for adding images to content from a gallery?
@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?And thanks for showing us this, I've now ditched Devise and feel cleansed.
As a side note Ryan, I've noticed our avatars are being cached here at Railscasts. I updated my account at Github months ago and I'm seeing old info here, is there a way we can force a refresh on our profile here at Railscasts?
I know I can edit my profile, but I can't change my Github account.
Thanks Ryan for a great intro to CoffeeScript - I've been eagerly anticipating an episode on this this.
And thank you to Trevor Burnham for your comments. I can see now why I should learn CoffeeScript. It didn't quite click that I'd be moving any syntax errors into compile time until I read your comment. That's a big plus in my opinion. I look forward to buying and reading your book.
As a side note, I've just taken a fresh look at HAML because I started playing around with ActiveAdmin. I must say I really must have been in a bad mood the last time I looked at it because now it really does seem appealing. I will have to play with it a little more too I think (even though it's not a default in the Rails stack)!
If nothing else Rails is teaching me to be more open-minded.
Awesome episode Ryan. I needed this in an existing Rails 2.3.8 project, so I made a few changes to suit.
If anyone is interested, my fork is at: https://github.com/MeetDom/railscasts-episodes/tree/rails238/episode-255
Includes the sqlite3 db with products and has fixes to deal with undoing a create which was throwing an ActiveRecord::RecordNotFound error. I substituted @template for view_context since it's not available in until Rails 3.
Hope this helps someone else still using Rails 2.3.8.