RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

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.

Avatar

I just want to know how you get all that content to appear by snapping your fingers :)

keep up the great work.

Avatar

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

Avatar

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.

Avatar

Any suggestions on migrating an existing devise db to use this scratch-built solution?

Avatar

Refer to "ranked model" in @Jean's comment above

Avatar

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:

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. :)

Avatar

This spelling error just got me too.
Robert Jackson below has the fix.
asciicasts doesn't seem to have a contact either :(

Avatar

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

Avatar

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.

Avatar

Channels aren't necessarily created, they are just a name given to determine which messages are sent to which users.

Avatar

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

Avatar

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

Avatar

Also - America in South America means South America

Avatar

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?

Avatar

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!!

Avatar

Can i configure different delay time between jobs calls for different queues?

Avatar

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!

Avatar

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.

Avatar

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. ;-)

Avatar

$('#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 holding

Avatar

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/" )

ruby
class Chatroom < ActiveRecord::Base
before_create do |chatroom|
    generate_hex_token(:room_key)
    generate_token(:room_password)
  end
  def generate_token(column)
    begin
      self[column] = SecureRandom.base64.tr("+/=*", "-_")
    end while Chatroom.exists?(column => self[column])
  end
  
  def generate_hex_token(column)
    begin
      self[column] = SecureRandom.hex(4).tr("+/", "-_")
    end while Chatroom.exists?(column => self[column])
  end
end
Avatar

Could you write or refer me to some explanation on how you did it?

Avatar

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?

Avatar

What are channels and how do you create them? I probably should google this first but then, right place right time to ask?

Avatar

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.

Avatar

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?

  • Kai
Avatar

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

Avatar

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
class MessageController < ApplicationController
  def message
    # 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
    end
  end
end
Avatar

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.

Avatar

There is a faye-rails gem which makes integration much easier.

  • Thin client is automatically started and stopped with your rails server
  • faye.js is integrated with assets pipeline
  • Integration with Rails routing, models and controllers

Just put this in your routes file:

ruby
  faye_server '/faye', timeout: 25 do
    listen(9292)
  end

and then this in your application.js

javascript
  \\= require faye-browser-min

Browse to localhost:9292 and you should find everything works.

Avatar

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

NoMethodError in Articles#index

Showing app/views/articles/index.html.erb where line #12 raised:

You have a nil object when you didn't expect it!
The error occurred while evaluating nil.strftime

Extracted source (around line #12):

9:
10: <% calendar_for @articles, :year => @date.year, :month => @date.month do |calendar| %>
11: <%= calendar.head('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday') %>
12: <% calendar.day(:day_method => :published_on) do |date, articles| %>
13: <%= date.day %>
14:
15: <% for article in articles %>

RAILS_ROOT: /home/markn/myRailsApps/blog
Application Trace | Framework Trace | Full Trace

/home/markn/myRailsApps/blog/vendor/plugins/table_builder/lib/table_builder/calendar_helper.rb:101:in objects_for_days'
/home/markn/myRailsApps/blog/vendor/plugins/table_builder/lib/table_builder/calendar_helper.rb:100:in
each'
/home/markn/myRailsApps/blog/vendor/plugins/table_builder/lib/table_builder/calendar_helper.rb:100:in objects_for_days'
/home/markn/myRailsApps/blog/vendor/plugins/table_builder/lib/table_builder/calendar_helper.rb:27:in
day'
/home/markn/myRailsApps/blog/vendor/plugins/table_builder/lib/table_builder/table_builder.rb:115:in tbody'
/home/markn/myRailsApps/blog/vendor/plugins/table_builder/lib/table_builder/calendar_helper.rb:26:in
day'
/home/markn/myRailsApps/blog/app/views/articles/index.html.erb:12:in _run_erb_app47views47articles47index46html46erb'
/home/markn/myRailsApps/blog/app/views/articles/index.html.erb:10:in >
_run_erb_app47views47articles47index46html46erb'

Request

Parameters:

None

Show session dump
Response

Headers:

{"Cache-Control"=>"no-cache",
"Content-Type"=>"text/html"}`

Does someby have any suggestions?

Thank you.

Avatar

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).

Avatar

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:

ruby
:host => request.domain
Avatar

To be more specific, if i use a redirect_to in my controller action

ruby
redirect_to sites_url(:subdomain => false), :notice => 'Logged out!'

it redirects me to the requested url but doesn't remove the subdomain

Avatar

something like

xxx_url(:subdomain => false) in rails 3.1

doesn't work anymore for me. Any ideas?

Avatar

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?

Avatar

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?

Avatar

Event handler declaration has changed in Mercury... try:

javascript
jQuery(function() {
  Mercury.on('ready', function() {
    var link = $('#mercury_iframe').contents().find('#edit_link');
    Mercury.saveURL = link.data('save-url');
    link.hide();
  });
  Mercury.on('saved', function() {
    window.location = window.location.href.replace(/\/editor\//i, '/');
  });
});
Avatar

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.

Avatar

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).

Avatar

Wondering the same thing. Anybody have any insights they can share?

Avatar

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?

Avatar

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

Avatar

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?