Best ruby-on-rails questions in October 2010

OmniAuth & Facebook: certificate verify failed

19 votes

I've followed Railscast #235 to try and set up a minimal Facebook authentication.

I've first set up a Twitter authentication, as done by Ryan himself. That worked flawlessly.

I then moved on to adding a Facebook login. However, after authorizing the app the redirect to /auth/facebook/callback fails with:

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

I am working on localhost. I didn't set up any SSL within the app. What am I doing wrong?

The real problem is that Faraday (which Omniauth/Oauth use for their HTTP calls) is not wasn't setting the ca_path variable for OpenSSL. At least on Ubuntu, most root certs are stored in "/etc/ssl/certs". Since Faraday isn't wasn't setting this variable (and currently does not have a method to do so), OpenSSL isn't wasn't finding the root certificate for Facebook's SSL certificate.

I've submitted a pull request to Faraday which will add support for this variable and hopefully they will pull in this change soon. Until then, you can monkeypatch faraday to look like this or use my fork of Faraday. After that, you should specify version 0.3.0 of the OAuth2 gem in your Gemspec which supports the passing of SSL options through to Faraday. All you need to do now is upgrade to Faraday 0.6.1, which supports passing of the ca_path variable and upgrade to OmniAuth 0.2.2, which has the proper dependencies for OAuth2. You'll then be able to properly fix this issue by just adding the following to your Omniauth initializer:

Rails.application.config.middleware.use OmniAuth::Builder do
    provider :facebook, FACEBOOK_KEY, FACEBOOK_SECRET, {:client_options => {:ssl => {:ca_path => "/etc/ssl/certs"}}}
end

So, to recap:

  1. Faraday needs to be updated to support SSL ca_path. Install Faraday 0.6.1
  2. Your app needs to use OAuth2 version 0.3.0. You may need to fork omniauth since it currently has a minor version dependency in the 0.2.x tree. Upgrade to OmniAuth 0.2.2
  3. Modify your provider initializer to point to your system's certificate path ("/etc/ssl/certs" on Ubuntu et al)

Hopefully the next releases of both Faraday and Omniauth will incorporate this solution.

Thanks to KirylP above for setting me on the right path.

Using God to monitor Unicorn - Start exited with non-zero code = 1

16 votes

I am working on a God script to monitor my Unicorns. I started with GitHub's examples script and have been modifying it to match my server configuration. Once God is running, commands such as god stop unicorn and god restart unicorn work just fine.

However, god start unicorn results in WARN: unicorn start command exited with non-zero code = 1. The weird part is that if I copy the start script directly from the config file, it starts right up like a brand new mustang.

This is my start command:

/usr/local/bin/unicorn_rails -c /home/my-linux-user/my-rails-app/config/unicorn.rb -E production -D

I have declared all paths as absolute in the config file. Any ideas what might be preventing this script from working?

I haven't used unicorn as an app server, but I've used god for monitoring before.

If I remember rightly when you start god and give your config file, it automatically starts whatever you've told it to watch. Unicorn is probably already running, which is why it's throwing the error.

Check this by running god status once you've started god. If that's not the case you can check on the command line what the comand's exit status is:

/usr/local/bin/unicorn_rails -c /home/my-linux-user/my-rails-app/config/unicorn.rb -E production -D; echo $?;

that echo will print the exit status of the last command. If it's zero, the last command reported no errors. Try starting unicorn twice in a row, I expect the second time it'll return 1, because it's already running.

Migrating from Authlogic to Devise

15 votes

I've previously implemented Authlogic for authorization on my site. Now however I wish to switch over to using Devise instead, and I'm wondering if anyone has any experience with this. Perhaps anyone's seen a blog post on the subject?

Thank you.

I myself switched from Authlogic to Devise recently and also didn't find any articles. However, in the simple case, once you've thrown away all of your user_session and other authlogic-related code, the main piece of work is converting your old users table to the format expected by devise.

My old table looked like this:

      Column       |           Type           |                     Modifiers                      
-------------------+--------------------------+----------------------------------------------------
 id                | integer                  | not null default nextval('users_id_seq'::regclass)
 login             | character varying(256)   | not null
 password          | character varying(64)    | not null
 created_at        | timestamp with time zone | not null
 updated_at        | timestamp with time zone | not null
 persistence_token | character varying(255)   | not null
Indexes:
    "users_pkey" PRIMARY KEY, btree (id)
    "index_users_on_persistence_token" UNIQUE, btree (persistence_token)
    "users_login_key" UNIQUE, btree (login)

and I determined that the table would have to contain at least the following info for devise (with many optional features enabled):

 id                   | integer                     | not null default nextval('contributors_id_seq'::regclass)
 email                | character varying(255)      | not null default ''::character varying
 encrypted_password   | character varying(128)      | not null default ''::character varying
 password_salt        | character varying(255)      | not null default ''::character varying
 confirmation_token   | character varying(255)      | 
 confirmed_at         | timestamp without time zone | 
 confirmation_sent_at | timestamp without time zone | 
 reset_password_token | character varying(255)      | 
 remember_token       | character varying(255)      | 
 remember_created_at  | timestamp without time zone | 
 sign_in_count        | integer                     | default 0
 current_sign_in_at   | timestamp without time zone | 
 last_sign_in_at      | timestamp without time zone | 
 current_sign_in_ip   | character varying(255)      | 
 last_sign_in_ip      | character varying(255)      | 
 failed_attempts      | integer                     | default 0
 unlock_token         | character varying(255)      | 
 locked_at            | timestamp without time zone | 
 created_at           | timestamp without time zone | 
 updated_at           | timestamp without time zone | 

So I defined an unadorned activerecord class in the migration class

 class ConversionUser < ActiveRecord::Base
   set_table_name "users"
 end

and then here's the "up" migration code I ended up using (with PostgreSQL):

add_column :users, :email, :string, :limit => 255
execute "UPDATE users SET email = login || '@somedomain.net'"
execute "ALTER TABLE users ALTER email SET NOT NULL"

add_column :users, :encrypted_password, :string, :limit => 128
add_column :users, :password_salt, :string, :limit => 255

require 'devise/encryptors/bcrypt'
ConversionUser.find(:all).each do |u|
  password_salt = Devise::Encryptors::Bcrypt.salt(Devise.stretches)
  u.update_attributes!(:password_salt => password_salt,
                       :encrypted_password => Devise::Encryptors::Bcrypt.digest(u.password, Devise.stretches, password_salt, Devise.pepper))
end

add_column :users, :confirmation_token, :string, :limit => 255
add_column :users, :confirmed_at, :timestamp
add_column :users, :confirmation_sent_at, :timestamp
execute "UPDATE users SET confirmed_at = created_at, confirmation_sent_at = created_at"
add_column :users, :reset_password_token, :string, :limit => 255

add_column :users, :remember_token, :string, :limit => 255
add_column :users, :remember_created_at, :timestamp
add_column :users, :sign_in_count, :integer, :default => 0
add_column :users, :current_sign_in_at, :timestamp
add_column :users, :last_sign_in_at, :timestamp
add_column :users, :current_sign_in_ip, :string, :limit => 255
add_column :users, :last_sign_in_ip, :string, :limit => 255

add_column :users, :failed_attempts, :integer, :default => 0
add_column :users, :unlock_token, :string, :limit => 255
add_column :users, :locked_at, :timestamp

remove_column :users, :password
remove_column :users, :persistence_token

add_index :users, :email,                :unique => true
add_index :users, :confirmation_token,   :unique => true
add_index :users, :reset_password_token, :unique => true
add_index :users, :unlock_token,         :unique => true

Note that here I've converted a plain password column into a bcrypt-encrypted column for Devise -- if you've used encrypted passwords with Authlogic, then you'll probably want to just rename the column (if necessary) and choose the correct encryptor module in config/initializers/devise.rb.

For reference, the "devise" clause in my User model looks like this:

devise :database_authenticatable, :registerable, :recoverable,
  :rememberable, :trackable, :validatable, :confirmable, :lockable,
  :timeoutable, :authentication_keys => [ :login ]

Note that overriding :authentication_keys like this so that users sign in with their login rather than their email address required me to modify some of the devise views: rails generate devise:views, then edit the files.

Hope this helps a bit. Good luck!

Is there an advantage to running JRuby if you don't know any Java?

14 votes

I've heard great things about JRuby and I know you can run it without knowing any Java. My development skills are strong, Java is just not one of the tools I know. It's a massive tool with a myriad of accompanying tools such as Maven/Ant/JUnit etc.

Is it worth moving my current Rails applications to JRuby for performance reasons alone? Perhaps if I pick up some basic Java along side, there can be so added benefits that aren't obvious such as better debugging/performance optimization tools?

Would love some advice on this one.

I think you pretty much nailed it:

JRuby is just yet another Ruby execution engine, just like MRI, YARV, IronRuby, Rubinius, MacRuby, MagLev, SmallRuby, Ruby.NET, XRuby, RubyGoLightly, tinyrb, HotRuby, BlueRuby, Red Sun and all the others.

The main differences are:

  • portability: for example, YARV is only officially supported on x86 32 Bit Linux. It is not supported on OSX or Windows or 64 Bit Linux. Rubinius only works on Unix, not on Windows. JRuby OTOH runs everywhere: desktops, servers, phones, App Engine, you name it. It runs on the Oracle JDK, OpenJDK, IBM J9, Apple SoyLatte, RedHat IcedTea and Oracle JRockit JVMs (and probably a couple of others I forgot about) and also on the Dalvik VM. It runs on Windows, Linux, OSX, Solaris, several BSDs, other proprietary and open Unices, OpenVMS and several mainframe OSs, Android and Google App Engine. In fact, on Windows, JRuby passes more RubySpec tests than "Ruby" (meaning MRI or YARV) itself!

  • extensibility: Ruby programs running on JRuby can use any arbitrary Java library. Through JRuby-FFI, they can also use any arbitrary C library. And with the new C extension support in JRuby 1.6, they can even use a large subset of MRI and YARV C extensions, like Mongrel for example. (And note that "Java" or "C" library does not actually mean written in those languages, it only means with a Java or C API. They could be written in Scala or Clojure or C++ or Haskell.)

  • tooling: whenever someone writes a new tool for YARV or MRI (like e.g. memprof), it turns out that JRuby already had a tool 5 years ago which does the same thing, only better. The Java ecosystem has some of the best tools for "runtime behavior comprehension" (which is a term I just made up, by which I mean much more than just simple profiling, I mean tools for deeply understanding what exactly your program does at runtime, what its performance characteristics are, where the bottlenecks are, where the memory is going, and most importantly why all of that is happening) and visualization available on the market, and pretty much all of those work with JRuby, at least to some extent.

  • deployment: assuming that your target system already has a JVM installed, deploying a JRuby app (and I'm not just talking about Rails, I also mean desktop, mobile, other kinds of servers) is literally just copying one JAR (or WAR) and a double-click.

  • performance: JRuby has much higher startup overhead. In return you get much higher throughput. In practice, this means that deploying a Rails app to JRuby is a good idea, as is running your integration tests, but for developer unit tests and scripts, MRI, YARV or Rubinius are better choices. Note that many Rails developers simply develop and unit test on MRI and integration test and deploy on JRuby. There's no need to choose a single execution engine for everything.

  • concurrency: JRuby runs Ruby threads concurrently. This means two things: if your locking is correct, your program will run faster, and if your locking is incorrect, your program will break. (Unfortunately, neither MRI nor YARV nor Rubinius run threads conurrently, so there's still some broken multithreaded Ruby code out there that doesn't know it's broken, because obviously concurrency bugs can only show up if there's actual concurrency.)

  • platforms (this is somewhat related to portability): there are some amazing Java platforms out there, e.g. the Azul JCA with 768 GiBytes of RAM and 864 CPU cores specifically designed for memory-safe, pointer-safe, garbage-collected, object-oriented languages. Android. Google App Engine. All of those run JRuby.

How do I make an RSS/Atom feed in Rails 3?

12 votes

I'm pretty new to Rails 3, and I'm trying to make an RSS/Atom feed. I know about auto_discovery_link_tag, but what is the associated controller/action supposed to look like?

Thanks!

Auto_discovery_link_tag is a good start. A quick Google search and I found blog posts on How to Create an RSS feed in Rails. Let me fill you in on what your associated controller/action is supposed to look like:

controllers/posts_controller.rb

def feed
    @posts = Post.all(:select => "title, author, id, content, posted_at", :order => "posted_at DESC", :limit => 20) 

    respond_to do |format|
      format.html
      format.rss { render :layout => false } #index.rss.builder
    end
end

The name of this file should match the controller. See, below:

views/posts/feed.rss.builder

xml.instruct! :xml, :version => "1.0" 
xml.rss :version => "2.0" do
  xml.channel do
    xml.title "Your Blog Title"
    xml.description "A blog about software and chocolate"
    xml.link posts_url

    for post in @posts
      xml.item do
        xml.title post.title
        xml.description post.content
        xml.pubDate post.posted_at.to_s(:rfc822)
        xml.link post_url(post)
        xml.guid post_url(post)
      end
    end
  end
end

This is where all the Railsy magic happens. Here, the RSS feed XML is generated and returned to HTTP.

Processing third party payments (using PayPal) while taking a percentage

11 votes

I know it's possible to sit between a payer and payee using PayPal by just storing payee's PayPal account information.

Is it possible to take a percentage of the that transaction and pay it to a different PayPal account. Basically acting as a service fee for using our website?

If it helps, I would probably be using Active Merchant for rails.

What you are looking for is called "Chained Payments". You can take a commission from a payment, and the remainder can be split with one or more payees. The original payer only sees you. Chained payments are one of the several types of workflows you can get through the "Adaptive Payments" API.

More info on:

https://www.x.com/servlet/JiveServlet/download/1044-1-1033/pp_dev_Datasheet_APC_R3.pdf

and pages 18 and 19 of the following manual on Adaotive Payments manual at cms.paypal.com/cms_content/US/en_US/files/developer/PP_AdaptivePayments.pdf

How do I attach a prawnto-rendered .pdf to an email in Rails 2.3.5?

11 votes

My application creates a .pdf file when it is rendered by passing it to the URL (for example, domain.com/letter/2.pdf)

It doesn't get saved anywhere.

How can I make that actual pdf an attachment in an outbound email.

Here is my mailer:

  def campaign_email(contact,email)
    subject    email.subject
    recipients contact.email
    from       'Me <me@me.com>'
    sent_on    Date.today

    attachment = File.read("http://localhost:3000/contact_letters/#{attachment.id}.pdf")

   attachment "application/pdf" do |a|
    a.body = attachment
    a.filename = "Othersheet.pdf" 
   end
 end

This is the controller that creates/renders the PDF:

def create
    @contact_letter = ContactLetter.new(params[:contact_letter])

    @contact = Contact.find_by_id(@contact_letter.contact_id)
    @letter = Letter.find_by_id(@contact_letter.letter_id)

    if @contact_letter.save
      flash[:notice] = "Successfully created contact letter."

      #redirect_to contact_path(@contact_letter.contact_id)
      redirect_to contact_letter_path(@contact_letter, :format => 'pdf')
    else
      render :action => 'new'
    end
  end

NOTE: I hardcoded localhost:3000/ how can I substitute that with a variable so that on dev it is localhost:3000 and on production is it the correct domain? Is there a way to include routing in this?)

ERROR: I get an

Invalid argument - http://localhost:3000/contact_letters/9.pdf

I got it to work by passing the pdf object directly into the campaign_email method and then assigning an attachment.

Where/How to code Constants in Rails 3 Application

9 votes

I am interested in doing this the "Rails Way" on a new application. I would also like to refer to constants in some sort of context to make the code more readable. I have an application where a user can request access to another users's data set. This AccessRequest can have one of the following statuses:

Review Denied Approved

I can see these values being used in reporting features in the future, so I want to make them constants in order to avoid any spelling or capitalization issues. I thought I would just put these in a constants.rb file in the config/initializers directory.

I would like to refer to these as AccessRequest::REVIEW. Since I already have a model called AccessRequest, does it make sense to put them there? Or wrap them in a class in a constants.rb file in the config/initializers directory? Which way is the Rails Way?

Belated reply, but posting as this answer still comes up in search results. Putting the constant in the model makes sense as the constant pertains directly to it. Using the Rails application config to store constants is incorrect.

As per the comment listed in application.rb:

# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded

This is still valid as of Rails 3.

Rails 3 SSL routing redirects from https to http

9 votes

This question relates to this SO question and answer (rails-3-ssl-deprecation ) where its suggested to handle ssl in rails 3 using routes.rb and routes like:

resources :sessions, :constraints => { :protocol => "https" }

# Redirect /foos and anything starting with /foos/ to https.
match "foos(/*path)", :to => redirect { |_, request|  "https://" + request.host_with_port + request.fullpath }

My problem is that links use relative paths(i think thats the correct term) and once I'm on a https page all the other links to other pages on the site then use https.

1) Whats the best way to get back to http for pages where https isn't required? Do I have to setup redirects for all them(I hope note) or is there a better way. Would the redirects be like this:

match "foos(/*path)", :to => redirect { |_, request|  "http://" + request.host_with_port + request.fullpath }

2) If redirects back to http are required, how do I handle a case where I want all methods to be http except one? ie foos(/*path) would be for all foos methods. But say I wanted foos/upload_foos to use ssl. I know how to require it

scope :constraints => { :protocol => "https" } do
  match 'upload_foos' => 'foos#upload_foos', :via => :post, :as => :upload_foos 
end

but if I put in the http redirect to the foos path what happens to https upload_foos?

If you want all your links to be able to switch between http and https, you have to stop using the _path helper and switch to _url helpers.

After that, using a scope with the protocol parameter forced and protocol constraint makes the urls automatically switch.

routes.rb
scope :protocol => 'https://', :constraints => { :protocol => 'https://' } do
  resources :sessions
end

resources :gizmos

And now in your views:

<%= sessions_url # => https://..../sessions %>
<%= gizmos_url   # => http://..../gizmos %>

Edit

This doesn't fix urls that go back to http when you are in https. To fix that you need to override url_for.

In any helper
module ApplicationHelper
  def url_for(options = nil)
    if Hash === options
      options[:protocol] ||= 'http'
    end
    super(options)
  end
end

This will set the protocol to 'http' unless it was explicitly set (in routes or when calling the helper).

How to deploy a [Ruby on Rails] site in a scalable way?

8 votes

I have been working on my [first] startup for a month now, and while it's probably atleast one more month away from an alpha release, I want to know how to deploy it the right way. The site will have an initial high amount of load (network + CPU) for a new user, so I am thinking of having a separate server/queue for this initial process, so that it doesn't slow down the site for existing users.

Based on my research so far, I am currently leaning towards nginx + haproxy + unicorn/thin + memcached + mysql, and deploying on Linode. However, I have no prior experience in any of the above; hence I am hoping to tap the community's experience.

  • Does the above architecture seem reasonable? Any suggestions/articles/books that you would recommend?
  • Is Linode a good choice? Heroku/EY seem too expensive for me (atleast until I have enough revenue), but am I missing some other better option? MediaTemple?
  • Any good suggestions on the load balancing architecture? I am still reading up on this.
  • Is it better have 2 separate Rails server instances on 2 separate linodes, or running 1 instance on a linode of twice capacity (in terms of RAM/storage/bandwidth)? How many Linodes should I start with?
  • Which Linux distribution should I choose? (Linode offers 8 different ones - http://www.linode.com/faq.cfm) Are there any relative advantages/disadvantages between them for a Rails site?

I apologize if any of my questions are stupid or contradictory; please attribute it to my inexperience.

Architecture

You're on the right track. I personally prefer Passenger over thin/unicorn (having run nginx to thin backends for a long while) just for the convenience, but your proposed setup is fairly standard. If you're on Ruby 1.8.7, I'd recommend that you consider REE + Passenger for framework memory savings, though.

Hosting & Load Balancing

Linode is fantastic, and I use them for just about everything I can, but you will need to be aware of RAM limits. Each Rails processes uses a nontrivial amount of RAM, and you'll want to avoid getting the machine into swap. Plan on running enough Rails instances per machine so that your memory allocation is about 90% of the memory on the Linode. You'll likely want another Linode dedicated to your database, though you can start with them both on the same machine; just be prepared to split off MySQL as you grow. You can set up communications between Linodes in the same data center on private IPs, which don't count against your bandwidth quota.

Your scaling strategy should be as horizontal as possible, so I'd recommend just getting a second Linode and adding it to your haproxy pool when you need more horsepower - Linode charges you $20 for 512mb more RAM, or you can just get a whole 'nother Linode (with CPU, RAM, HDD, and bandwidth quota) for that same $20. Seems a no-brainer!). In Rails' case, an instance is an instance is an instance, so it really doesn't matter if it's on the same VM or not, as long as the time to connect to your database machine or whatnot are more or less the same. You could be running 10 Linodes each running 10 Rails processes apiece without much of an issue. Linode also offers IP failover, so that if your primary Linode (with haproxy) goes down, it can fail over automatically to a secondary Linode, which you would then have haproxy running on, and ready to act in the same capacity as the first.

Distribution

Honestly, this is up to you! Many folks go with Ubuntu or Redhat (CentOS/Fedora) distros - I like CentOS myself - but it's really just about what you feel most comfortable with. If you don't have a favorite distro, I would recommend trying Ubuntu/CentOS, as they tend to be quite friendly to the beginner, and have extremely robust community support.

You will probably want to pick a 32-bit distro unless you have a compelling reason to pick a 64-bit distro; 64-bit executables require more RAM than their 32-bit counterparts, and since RAM is likely to be your most precious resource, it makes sense to save it where you can.

In Ruby on Rails, what's the difference between DateTime, Timestamp, Time and Date?

8 votes

In my experience, getting dates/times right when programming is always fraught with danger and difficulity.

Ruby and Rails have always eluded me on this one, if only due to the overwhelming number of options; I never have any idea which I should pick.

When I'm using Rails and looking at ActiveRecord datatypes I can find the following

:datetime, :timestamp, :time, and :date

and have no idea what the differences are or where the gotchas lurk.

What's the difference? What do you use them for? Please advise. Thanks!

(P.S. I'm using Rails3)

The difference between different date/time formats in ActiveRecord have little to do with Rails and everything to do with whatever database you're using.

Using MySQL as an example (if for no other reason because it's most popular), you have DATE, DATETIME, TIME and TIMESTAMP column data types; just as you have CHAR, VARCHAR, FLOAT and INTEGER.

So, you ask, what's the difference? Well, some of them are self-explanatory. DATE only stores a date, TIME only stores a time of day, while DATETIME stores both.

The difference between DATETIME and TIMESTAMP is a bit more subtle: DATETIME is formatted as YYYY-MM-DD HH:MM:SS. Valid ranges go from the year 1000 to the year 9999 (and everything in between. While TIMESTAMP looks similar when you fetch it from the database, it's really a just a front for a unix timestamp. Its valid range goes from 1970 to 2038. The difference here, aside from the various built-in functions within the database engine, is storage space. Because DATETIME stores every digit in the year, month day, hour, minute and second, it uses up a total of 8 bytes. As TIMESTAMP only stores the number of seconds since 1970-01-01, it uses 4 bytes.

You can read more about the differences between time formats in MySQL here.

In the end, it comes down to what you need your date/time column to do. Do you need to store dates and times before 1970 or after 2038? Use DATETIME. Do you need to worry about database size and you're within that timerange? Use TIMESTAMP. Do you only need to store a date? Use DATE. Do you only need to store a time? Use TIME.

Having said all of this, Rails actually makes some of these decisions for you. Both :timestamp and :datetime will default to DATETIME, while :date and :time corresponds to DATE and TIME, respectively.

This means that within Rails, you only have to decide whether you need to store date, time or both.

Rails tests can't find test_helper

8 votes

I'm trying to run individual tests through ruby test/unit/mytest.rb, but I always get a "no such file to load - test_helper" error. Google brought up a few suggestions, but none of them worked for me. I'm running Rails 3.0, Ruby 1.9.2 (through RVM) on Ubuntu 10.10

Here's what I've tried so far - any suggestions really appreciated

  • Changed the "require test_helper" to "require File.dirname(FILE) + "/../test_helper" " in test/unit/mytest_test.rb. It brings back " no such file to load -- test/unit/../test_helper"
  • Tried running rvm test/unit/mytest_test.rb Same as above
  • Tried running ruby -I test/unit/mytest_test.rb. No messages to the terminal. After about 5 minutes waiting for something to happen, ctrl+c'd out of it

Any suggestions very appreciated - I'm stumped.

ruby 1.9.2 removed ".", the current directory, from the load path. I have to do this to get it to work:

require 'test_helper'

and call it like:

ruby -I. unit/person_test.rb 

Has anyone used omniauth with rails 2.3.8?

7 votes

I am new to Rails and I am trying to use omniauth with rails 2.3.8. I couldn't find any tutorial for this version of rails so I referred to http://blog.railsrumble.com/blog/2010/10/08/intridea-omniauth.

I added the initializer as follows:

omniauth.rb

OmniAuth::Strategies::Twitter = { 
    :consumer_key => 'xxxxxx', 
    :consumer_secret => 'xxxxxx' 
} 

After this step if I try to hit the URL '/auth/twitter' then I get "No route matches "/auth/twitter" with {:method=>:get}".

Has anyone used omniauth with rails 2.3.8? Please help.

Thanks & Regards,

Govind N

OmniOauth is a Rack::Middleware. So you need use it like that.

So you need add like that :

ActionController::Dispatcher.middleware.use OmniAuth::Strategies::Twitter = { 
    :consumer_key => 'xxxxxx', 
    :consumer_secret => 'xxxxxx' 
} 

Rails tutorial for the dumbest person in the world (me)?

6 votes

It is very difficult for me to find Rails tutorials (or books are also great) for my requirements:

  1. Stupidity
  2. Ruby 1.9 or lastest 1.8
  3. MySQL
  4. A Game (simple roll play)
  5. JQuery front

Thanks you!

The Rails Guides are great and easy on the eyes too.

What does Rails 3 session_store domain :all really do?

6 votes

Updated question to make it more clear

I understand that you can set the domain of your session_store to share sessions between subdomains like this: Rails.application.config.session_store :cookie_store, :key => '_my_key', :domain => "mydomain.com"

in Rails 3, what does the setting :domain => :all do? It can't let you share sessions across top-level domains, cookies can't do that. The documentation says it assumes one top level domain. So what happens if multiple domains access your app?

In my app, my users can create personal subdomains of one main domain, but then can also access that subdomain via their own custom domain.

What is the correct session_store domain setting so that I can: a) share sessions across all domains of my primary domain, eg "mydomain.com" b) users who access their personal subdomain eg "user1.mydomain.com" via a CNAME custom url like "some.otherdomain.com" can still create separate sessions.

Thanks

OK, the way to accomplish this is to set the domain on the session cookie dynamically. To do this early enough it should be done as rack middleware:

# Custom Domain Cookie
#
# Set the cookie domain to the custom domain if it's present
class CustomDomainCookie
  def initialize(app, default_domain)
    @app = app
    @default_domain = default_domain
  end

  def call(env)
    host = env["HTTP_HOST"].split(':').first
    env["rack.session.options"][:domain] = custom_domain?(host) ? ".#{host}" : "#{@default_domain}"
    @app.call(env)
  end

  def custom_domain?(host)
    host !~ /#{@default_domain.sub(/^\./, '')}/i
  end
end

Ajax pagination like Twitter

5 votes

Is there any plugin/gem or an easy way for accomplish a pagination functionality like Twitter?

This means, showing a "More" button that shows more posts (for example) below once it's clicked, using Ajax.

If there's any easy way for modifying something from will_paginate plugin, that would be useful too.

I use this for easy pageless pagination. Seems to be a better solution w/o the more button.

http://github.com/jney/jquery.pageless

Real time apps: Socket.io vs Pusherapp

4 votes

What are the factors you would consider when choosing between Socket.io and Pusherapp?

http://Socket.io
http://pusherapp.com

Important considerations includes: integration w existing systems like rails/django, ease of setup, ease of development

Socket.io is using Ajax long polling which requires more resources. Pusherapp on the other hand is real push. Pusherapp has various libraries, they have gem for rails, wrappers for python and GAE. You can also try other services like:

  1. Pubnub
  2. Beaconpush
  3. Hookbox
  4. Pubsubhubbub (using XMPP instead of websockets)
  5. Kwwika