How to change the default rails server in Rails 3? - ruby-on-rails

I'm new to Rails and I'm wondering if there is an option to change the default rails server, i.e., webrick, for another one such as 'puma' or 'thin'. I know it is possible to specify which server to run with 'rails server' command, however I would like to use this command without specify the name of the server so it can run the default rails server. Is there a way to change the default rails server into a configuration file or something like this? Thanks in advance for your help!

Based on James Hebden's answer:
Add Puma to gemfile
# Gemfile
gem 'puma'
Bundle install it
bundle
Make it default, paste this code into script/rails above require 'rails/commands':
require 'rack/handler'
Rack::Handler::WEBrick = Rack::Handler.get(:puma)
So script/rails (in Rails 3.2.12) will look like:
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rack/handler'
Rack::Handler::WEBrick = Rack::Handler.get(:puma)
require 'rails/commands'
Run server
rails s
=> Booting Puma

Rack (the interface between rails and a web server) has handlers for the default WEBrick, and also for Thin. If you place the following in your Gemfile in the root of your rails project
gem 'thin'
rails server will automatically use Thin. This has been the case since 3.2rc2.
This unfortunately only applies to Thin, as Rack does not have built-in support for Unicorn, and others.
For servers that have Rack handlers (again, sadly Unicorn does not), you can do a bit of a hack to get rails server to use them. In your scripts/rails file in the root of your rails project, you can add the below just above `require 'rails/commands'
require 'rack/handler'
Rack::Handler::WEBrick = Rack::Handler::<name of handler class>
This essentially resets the handler for WEBrick to point to the handler for the server you would like to use.
To get an understanding of the supported Rack handlers, take a look at the comments in the source: https://github.com/rkh/rack/blob/master/lib/rack/handler.rb

I think rails simply passes on the server option provided to rack. Rack has the following logic to determine what server to run:
https://github.com/rack/rack/blob/master/lib/rack/server.rb#L271-L273
def server
#_server ||= Rack::Handler.get(options[:server]) || Rack::Handler.default(options)
end
The first case is when a :server option was passed to the rails server command. The second is to determine the default. It looks like:
https://github.com/rack/rack/blob/master/lib/rack/handler.rb#L46-L59
def self.default(options = {})
# Guess.
if ENV.include?("PHP_FCGI_CHILDREN")
# We already speak FastCGI
options.delete :File
options.delete :Port
Rack::Handler::FastCGI
elsif ENV.include?("REQUEST_METHOD")
Rack::Handler::CGI
else
pick ['thin', 'puma', 'webrick']
end
end
Thin and Puma should be automatically picked up. The fallback is Webrick. Of course other web servers could override this behavior to make them the first in the chain.
If your Webserver is not picked up by default you could monkey-patch the default method to work like you want it. Of course this could break in future versions of rack.

Rack will now look at a RACK_HANDLER environment variable file to see if you've specified a default rack handler. You can add a line like this to your .env file to set the default if you're using dotenv, or specify the assignment from the command line.
`RACK_HANDLER=webrick`
This should work as of this pull request:
https://github.com/rack/rack/pull/590

I wouldn't get hung up on specifically using the rails server command. Just install whichever gem you want and alias the command (e.g. rails s Puma) to something simple like rs.

If you want unicorn/thin/etc, just add the gem to your gemfile
i.e. gem 'unicorn', gem 'thin', etc. then run bundle install at the command line.
As far as I can tell, adding either of these gems runs the appropriate server via rails server
UPDATE
Apparently this only works for Thin or Puma.

If you have thin in your Gemfile, you need to do this:
require 'rack/handler'
Rack::Handler::Thin = Rack::Handler.get(:puma)

If you use bash run: export RACK_HANDLER=webrick

Related

Ignore group in Rails Gemfile

I have the puma gem in my Rails 4.1.8 Gemfile because I want to use it as the default webserver in all environments. That works fine.
# Gemfile
gem "puma"
In development I am using mailcatcher which means that I'd like to include it as a dependency in my Gemfile.
# Gemfile
group :development do
gem "mailcatcher"
end
This causes the default webserver to be set to thin. This appears to be an unintended consequence of mailcatcher, but it brings up a specific question. Can I create a group that bundler obeys to install Gems, but that Rails ignores? I tried something like this but Rails is still loading the contained gems.
# Gemfile
group :mailcatcher do
gem "mailcatcher"
end
You can alias rails s command... For example export alias rs="rails server puma" and now rs will start puma. This way you are free to use any webserver you want )
If you want to make it really default you can add something like this
require 'rack/handler'
Rack::Handler::WEBrick = Rack::Handler.get(:puma)
to the rails script.
I don't know if this will work or not, but what about:
gem "mailcatcher", :require => false
Ref: Bundler: What does :require => false in a Gemfile mean?
Mailcatcher specifically states to not put it in your Gemfile.
Please don't put mailcatcher into your Gemfile. It will conflict with your applications gems at some point.
Instead, pop a note in your README stating you use mailcatcher. Simply run gem install mailcatcher then mailcatcher to get started.

What does "configure the gem in the config block of config/environment.rb" mean?

I'm writing my first Rails app. The app uses a lot of enumerations, so I'd like to include this gem that makes it easier to work with them.
I'm stumped by the installation instructions, though, which say
[...] For a rails application configure the gem in the config block of
the config/environment.rb file
config.gem "enumerated_attribute"
In my config/environment.rb I don't see anything that looks like a "config block".
config/environment.rb:
# Load the rails application
require File.expand_path('../application', __FILE__)
# Initialize the rails application
Webtet::Application.initialize!
So what does the author mean when he writes "configure the gem in the config block"?
Does he just want me to include this line in config/environment.rb
config.gem "enumerated_attribute"
?
Looks like this setup instruction was written for rails 2 application. If this gem works with rails 3 you just should add gem 'enumerated_attribute' to your Gemfile. Also you can try to use https://github.com/brainspec/enumerize gem (it works with rails 3 and has SimpleForm, Formtastic support and other awesome features)

Change default server for Rails

I installed the mongrel gem because I need it on my workstation for rare occasions, and now it's my default Rails (2) server. I know I could specify script/server webrick on the command line, but the fact is that I'd like to have my system (or app) default to webrick, and only use mongrel when specified.
Anybody know how to arrange that?
Specs: WinXP, Rails 2.3.12, Ruby 1.8.7
Ok here are a few options:
Option one - One off: Always add webrick as a command line arg
Open script/server and insert a line between the two requires
#!/usr/bin/env ruby
require File.expand_path('../../config/boot', __FILE__)
ARGV.unshift "webrick"
require 'commands/server'
Option two - Global: Edit the commands/server.rb file that launches rails
gem which railties -> tells you where the startup code is
Open the file at lib/commands/server.rb
Around line 45 edit the logic so that webrick is always launched by default.
server = Rack::Handler.get(ARGV.first) rescue nil
unless server
begin
server = Rack::Handler::WEBrick # was Mongrel
rescue LoadError => e
server = Rack::Handler::WEBrick
end
end
Option 3 - Cleanest but most involved:
Switch to Bundler and manage your dependencies directly. This is more work but positions you for switching to rails 3 at some point which might be nice depending on the life cycle of the application.
There's a tutorial for rails 2.3 here

Is there a way Rails 3.0.x can default to using Thin?

I run the Thin webserver for basically every app in my dev/test environments. When I used Mongrel with Rails 2.x, all I had to type was script/server to get it to run the webserver I choose. But with Rails 3, I have to specify Thin every time. Is there a way to get Thin running on my Rails apps by just typing rails s instead of rails s thin?
Yeah it's possible to do this.
The way the rails s command works at the end of the day is by falling through to Rack and letting it pick the server. By default the Rack handler will try to use mongrel and if it can't find mongrel it will go with webrick. All we have to do is patch the handler slightly. We'll need to insert our patch into the rails script itself. Here is what you do, crack open your script/rails file. By default it should look like this:
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands'
We insert our patch right before the require 'rails/commands' line. Our new file should look like this:
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rack/handler'
Rack::Handler.class_eval do
def self.default(options = {})
# Guess.
if ENV.include?("PHP_FCGI_CHILDREN")
# We already speak FastCGI
options.delete :File
options.delete :Port
Rack::Handler::FastCGI
elsif ENV.include?("REQUEST_METHOD")
Rack::Handler::CGI
else
begin
Rack::Handler::Mongrel
rescue LoadError
begin
Rack::Handler::Thin
rescue LoadError
Rack::Handler::WEBrick
end
end
end
end
end
require 'rails/commands'
Notice that it will now try Mongrel and if there is an error try for Thin and only then go with Webrick. Now when you type rails s we get the behaviour we're after.
As of Rails 3.2rc2, thin is now run by default on invoking rails server when gem 'thin' is in your Gemfile! Thanks to this pull request: https://github.com/rack/rack/commit/b487f02b13f42c5933aa42193ed4e1c0b90382d7
Works great for me.
In script/rails the following works as well:
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rack/handler'
Rack::Handler::WEBrick = Rack::Handler::Thin
require 'rails/commands'
Simply install thin, cd to the directory that your app is in and run thin start. Works perfectly here. :)
You can use http://www.softiesonrails.com/2008/4/27/using-thin-instead-of-mongrel to change as needed. (Its the one I used)

Trouble including httparty in ruby on rails

I've been trying to use HTTParty in my rails code
sudo gem install httparty
From the command line I can now successfully do
httparty "http://twitter.com/statuses/public_timeline.json"
When I try this in my rails app
require 'rubygems'
require 'httparty'
class FooController < ApplicationController
include HTTParty
def bar
blah = HTTParty.get("http://twitter.com/statuses/public_timeline.json")
end
end
I get the error message "no such file to load -- httparty"
I suspect there is something wrong with my environment?
You don't need to do 'include HTTParty' inside the Controller. Just remove that and it should work. I just tested it and it worked for me. If this doesn't work for you, you should add the gem to your environment.
Usually if you use a gem inside your Rails application, you should add the following to environment.rb:
config.gem "httparty"
The gem will be available in the application now and you don't need to add 'require' inside the Controller. Also, you don't need to require RubyGems inside a Controller.
When you use Rails 3, you need to put the following inside the Gemfile:
gem "httparty"
I hope it works for you. :)
The problem is, if you load a new gem, you have to restart the server even if you are in development.
I had this same error. I tried moving the require HTTParty all over, but found, all I needed to do was restart the rails server In the end I did not need to 'require HTTParty' nor 'include' it. It just needed to be loaded into rails.
1)include the httpary in your gemfile
open your gem file then add
gem 'httparty','YOUR VERSION NUMBER'
2) run bundle install in your command prompt of the app file
3) restart the server
Ran into the same problem. Then I switched from Ruby 1.8.7 to Ruby 1.9.2 and all errors varnished into thin air.
(Yes, it first took me quite some hours to come up with the possibility that the Ruby version might be the problem. Configured a secundairy server to avoid possible conflicts with 2 ruby versions, and after way to many hours I got my RoR stack up and running. And the first test with httparty (based on the example on top) worked out of the box! Finally can sleep RESTfully again :-)
I run into the same error whilst reviewing a project from a student, I change the name of the Gem from uppercase to lowercase then run bundle install. I then went ahead to change the format in which they were being imported from
require 'HTTParty' to require 'httparty' and boom it worked

Resources