This ended up being very simple. First of all, like other's have mentioned, it isn't required to save the salt. In fact, BCrypt now has much nicer helpers to create/check/save passwords. Here is a gist of the relevant lines from my User model. I use mongodb + mongoid and instead of renaming the encrypted_password field from devise (which is called the hash in the railcast) I just continue to use encrypted_password name (so no migration needed even for other db I think):
Another outstanding video - thank you! A question (perhaps a novice question):
how can I enable users to register so that all of the services record their "first_name" in the user model rather than "name" which is required in the auth hash schema?
It seems that omniauth-identity requires "name" while with omniauth-facebook I can distinguish between "name" and "first_name" and "last_name" when the user model creates records.
Remove hard dependency on bcrypt-ruby to avoid make ActiveModel dependent on a binary library. You must add the gem explicitly to your Gemfile if you want use ActiveModel::SecurePassword:
ruby
gem 'bcrypt-ruby', '~> 3.0.0'
This might help others that might be staring at an Error page, wondering why that gem wasn't required. @rbates You should add it to the show notes. :)
Weird, just got interested in Rack a week ago and here comes another good episode, by the way I found this screencast and I taught Ryan was covering basic things I already came across and instead I learn many new and useful stuff! - thanks thanks again
In private_pub, each subscription has its own unique signature/key. This means you can do something like auto-expire it after a period of time. If each chatroom has only one unique secret key then it is not possible to have control over each individual subscription.
I ran in to the following issue
with <%= f.collection_select :category_id, Category.find(:all), :id, :name, :prompt => "Select a Category" %>
we let user not to choose category_id, but use can also not type into create category field - so we let user to create product without category
if i add validation on cateory_id it did not save
But there is a problem. When try to record the data to db. There are lots of datas in ther e because of numbers of country and state field. For example you write name Bob, choose USA, and state NewYork. Datas are created many times Bob USA NewYork. Why?
Ryan this is great, I've been recently wondering about the possibility of using Rack to power a really simple web site that just barely isn't static, but doesn't require most of the power of Rails. I wasn't really sure where to start, but this is a fantastic intro and has me well on my way. Thanks!!
Someone correct me if I'm wrong but I'd assume since you have to fetch the migrations from the engine and run them on the consumer / main app it's likely they both would share the same data store (and thus this wouldn't work).
Not sure if there is a way to pass arbitrary data to the mounts to allow it to store data associated with a particular id (ie: blog 1, 2, 3 and then the data being associated with those). I assume you could somehow (although it sounds dirty) inspect the request and then use that to determine which instance the blog is and store / fetch its data using that means.
My gut tells me the best way to do this would rather to:
1. Have one engine for the blog
2. Have that engine understand the idea of there being more than one blog ... so there would be a blog model that has 0 to many posts, etc and then key the posts off blog so they are associated with that blog
3. Have the routes somehow handle pointing to the correct blog -- whether you want that to be /blog/1-Name-of-Blog/ etc or something else is your call.
Great screencast as always! Just wanted to let you know that I released my first RubyGem a few months ago (inspired by all the recent pub/sub libraries). It's called Mad Chatter. It's a host-your-pwn Ruby chat server using EventMachine and em-websocket. I'd love to get some feedback/advice/contributors. Maybe I'll switch to use private_pub. ;-)
Ryan what is the advantage of Private_pub compared to adding a key/ pass combination to model channels like this?
( And you have to listen to a channel like "/chatroom/new/room_key/room_pass/" )
Nice episode. I did the same few days ago using PusherApp together with Rbjs. It cleans up the Serverside Javascript pretty much and I ended up simply writing:
ruby
classMessageController < ApplicationControllerdefmessage# some logic here
publish_to @message.channel do
jQuery('#messages').append render @message
jQuery('#new_message_text').val ''if@message.user_id == current_user_id
endendend
Ryan, it is great that you show how to implement the whole thing from scratch. IMHO dependency on Redis and two gems isn't worth the functionality they add.
Custom solution might be easily optimized by using ActiveSupport memoize.
Mike's answer is awesome, just adding my two cents:
The find_by isn't supposed to fail in any way, you expect to find a blog for your subdomain. If it fails you probably want something to happen (an exception rather than a fallback).
I have an app that is using acts_as_tree and what I would like is for my url's on my page models to not include the model name, can friendly_id help with this?
I am testing the presence of particular page elements in views and can't figure out where such views testing belongs - controller tests with integrated views or integration tests. Could you elaborate on that a little in the future episodes?
As you guessed, the bang on the find_by_subdomain method is so it will raise RecordNotFound if the given subdomain does not exist.
A benefit of this would be so you could rescue_from RecordNotFound in the ApplicationController (or a specific controller) and redirect the user to another page with a flash message.
This has the added benefit of keeping your code DRY so you don't dirty up your controller actions by checking for a valid result and taking action accordingly.
I like endless scrolling except for one gotcha - it makes it very hard for users to access links on the page footer. One way to work around this is to use the jQuery Waypoints plugin to ensure that the footer is always displayed (despite the endless scrolling).
With a small little DSL that transforms into Javascript: https://github.com/buhrmi/rbjs
The code I wrote above, however, contains a bug that would reset the input field for all users.
I just want to know how you get all that content to appear by snapping your fingers :)
keep up the great work.
This ended up being very simple. First of all, like other's have mentioned, it isn't required to save the salt. In fact, BCrypt now has much nicer helpers to create/check/save passwords. Here is a gist of the relevant lines from my User model. I use mongodb + mongoid and instead of renaming the encrypted_password field from devise (which is called the hash in the railcast) I just continue to use encrypted_password name (so no migration needed even for other db I think):
https://gist.github.com/1637700
Another outstanding video - thank you! A question (perhaps a novice question):
how can I enable users to register so that all of the services record their "first_name" in the user model rather than "name" which is required in the auth hash schema?
It seems that omniauth-identity requires "name" while with omniauth-facebook I can distinguish between "name" and "first_name" and "last_name" when the user model creates records.
Any suggestions on migrating an existing devise db to use this scratch-built solution?
Refer to "ranked model" in @Jean's comment above
ACTIVE MODEL CHANGES RAILS 3.1.1
http://weblog.rubyonrails.org/2011/10/7/ann-rails-3-1-1
Remove hard dependency on bcrypt-ruby to avoid make ActiveModel dependent on a binary library. You must add the gem explicitly to your Gemfile if you want use ActiveModel::SecurePassword:
This might help others that might be staring at an Error page, wondering why that gem wasn't required. @rbates You should add it to the show notes. :)
This spelling error just got me too.
Robert Jackson below has the fix.
asciicasts doesn't seem to have a contact either :(
Weird, just got interested in Rack a week ago and here comes another good episode, by the way I found this screencast and I taught Ryan was covering basic things I already came across and instead I learn many new and useful stuff! - thanks thanks again
In
private_pub
, each subscription has its own unique signature/key. This means you can do something like auto-expire it after a period of time. If each chatroom has only one unique secret key then it is not possible to have control over each individual subscription.Channels aren't necessarily created, they are just a name given to determine which messages are sent to which users.
SSL isn't fully supported yet, but I hope to add it in a future version. See https://github.com/ryanb/private_pub/issues/18
I ran in to the following issue
with <%= f.collection_select :category_id, Category.find(:all), :id, :name, :prompt => "Select a Category" %>
we let user not to choose category_id, but use can also not type into create category field - so we let user to create product without category
if i add validation on cateory_id it did not save
Also - America in South America means South America
But there is a problem. When try to record the data to db. There are lots of datas in ther e because of numbers of country and state field. For example you write name Bob, choose USA, and state NewYork. Datas are created many times Bob USA NewYork. Why?
Ryan this is great, I've been recently wondering about the possibility of using Rack to power a really simple web site that just barely isn't static, but doesn't require most of the power of Rails. I wasn't really sure where to start, but this is a fantastic intro and has me well on my way. Thanks!!
Can i configure different delay time between jobs calls for different queues?
+1
Great episode! Have been programming ruby a long time and never seen those global variables.
I guess we normally use constants in an initializer like ROLLOUT = ...
only difference being your can't edit the constant later I guess.
Anyway, great info - thanks!
Someone correct me if I'm wrong but I'd assume since you have to fetch the migrations from the engine and run them on the consumer / main app it's likely they both would share the same data store (and thus this wouldn't work).
Not sure if there is a way to pass arbitrary data to the mounts to allow it to store data associated with a particular id (ie: blog 1, 2, 3 and then the data being associated with those). I assume you could somehow (although it sounds dirty) inspect the request and then use that to determine which instance the blog is and store / fetch its data using that means.
My gut tells me the best way to do this would rather to:
1. Have one engine for the blog
2. Have that engine understand the idea of there being more than one blog ... so there would be a blog model that has 0 to many posts, etc and then key the posts off blog so they are associated with that blog
3. Have the routes somehow handle pointing to the correct blog -- whether you want that to be /blog/1-Name-of-Blog/ etc or something else is your call.
Great screencast as always! Just wanted to let you know that I released my first RubyGem a few months ago (inspired by all the recent pub/sub libraries). It's called Mad Chatter. It's a host-your-pwn Ruby chat server using EventMachine and em-websocket. I'd love to get some feedback/advice/contributors. Maybe I'll switch to use private_pub. ;-)
$('#card_number').length
is returning the size of the jQuery collection -- just selecting an ID, so yes, the length will be 1.$('#card_number').val()
is the value currently which the input field is currently holdingRyan what is the advantage of Private_pub compared to adding a key/ pass combination to model channels like this?
( And you have to listen to a channel like "/chatroom/new/room_key/room_pass/" )
Could you write or refer me to some explanation on how you did it?
Looks pretty good! ;-)
Anyone tried running a Faye server on Heroku's cedar stack?
How about security, how easy/difficult is it for an unauthorized client to subscribe to a private channel?
What are channels and how do you create them? I probably should google this first but then, right place right time to ask?
If you have a huge amount of checkboxes you can just set a fixed height to the container of that checkboxes and set an overflow-y to scroll.
Hi Ryan,
what if i would like to use ssl for the faye server? With fay i could specify this in it's config. How to do this with private_pub?
Thanks so much for this one. There's also a decent tutorial on heroku's website that shows you how to build a static site using rack - link here http://devcenter.heroku.com/articles/static-sites-on-heroku
Nice episode. I did the same few days ago using PusherApp together with Rbjs. It cleans up the Serverside Javascript pretty much and I ended up simply writing:
+1
Good one:)
issues with rspec and sorcery !
http://stackoverflow.com/questions/8877300/testing-logging-in-function-of-sorcery-using-rspec-in-rails-3-1
Ryan, it is great that you show how to implement the whole thing from scratch. IMHO dependency on Redis and two gems isn't worth the functionality they add.
Custom solution might be easily optimized by using ActiveSupport memoize.
There is a faye-rails gem which makes integration much easier.
Just put this in your routes file:
and then this in your application.js
Browse to localhost:9292 and you should find everything works.
hello,
i'm newbie of rubby an rails.
i'm using ruby version 1.8.7 and rails version 2.3.2.
I just downloaded this sample source code and tried to use.
I got this error
Does someby have any suggestions?
Thank you.
Mike's answer is awesome, just adding my two cents:
The find_by isn't supposed to fail in any way, you expect to find a blog for your subdomain. If it fails you probably want something to happen (an exception rather than a fallback).
There is a closed issue on this matter. See https://github.com/rails/rails/issues/2025
I hope this is getting into rails 3.2.
In the meantime using the :host option works for me:
:host => request.domain
To be more specific, if i use a redirect_to in my controller action
it redirects me to the requested url but doesn't remove the subdomain
something like
xxx_url(:subdomain => false) in rails 3.1
doesn't work anymore for me. Any ideas?
I have an app that is using acts_as_tree and what I would like is for my url's on my page models to not include the model name, can friendly_id help with this?
Ryan, the series is amazing!
I am testing the presence of particular page elements in views and can't figure out where such views testing belongs - controller tests with integrated views or integration tests. Could you elaborate on that a little in the future episodes?
FYI, anyone attempting to add search through an association:
http://stackoverflow.com/questions/8867844/model-association-issue-in-rails/8868269#8868269
Event handler declaration has changed in Mercury... try:
As you guessed, the bang on the find_by_subdomain method is so it will raise RecordNotFound if the given subdomain does not exist.
A benefit of this would be so you could rescue_from RecordNotFound in the ApplicationController (or a specific controller) and redirect the user to another page with a flash message.
This has the added benefit of keeping your code DRY so you don't dirty up your controller actions by checking for a valid result and taking action accordingly.
I like endless scrolling except for one gotcha - it makes it very hard for users to access links on the page footer. One way to work around this is to use the jQuery Waypoints plugin to ensure that the footer is always displayed (despite the endless scrolling).
Wondering the same thing. Anybody have any insights they can share?
Nice screencast!
Why Ryan used find_by with a bang in the end? Is it for raising a RecordNotFound exception? What are the benefits of this practice?
I faced some difficulties on Sunspot (Solr). At the development, it runs fine. However, when i start running at production, it is connection refused.
My server is centos 6.0 with Nginx.
do i need to install the tomcat for the solr server? And solr is apache, can it run at nginx at production ?
Many Thanks
But... how can I change this
def new
@survey = Survey.new
3.times do
question = @survey.questions.build
4.times { question.answers.build }
end
end
In order to build as much as I want?
but I didn't work.