Last month, I posted 9 Ways to Use Rails Metal. This is the seventh way to use Rails Metal.
A week ago, I posted Ruby on Rails: Polymorphic Associations with Mixin Modules which included an example of tracking impressions on different objects.
Read More
analytics, Rails, Rails Metal, Ruby, Ruby on Rails, session
Serving static pages with Rails Metal is actually very simple. Here are the assumptions we’re making.
- Each static page’s content is made up of valid HTML.
- Each static page has a path and content stored in a StaticPage object as defined by the StaticPage model.
- If the path browsed matches the path in a StaticPage object, the content is what is to be delivered.
Here’s the code: Read More
HTML, Rails, Rails Metal, response, Ruby on Rails, tutorial
A few weeks ago, I wrote 9 Ways to Use Rails Metal. The third way to use Rails Metal was implementing a simple API.
Before I provide the code and an explanation, I’d like to cover a few things. First, this API only requires an API key. If you want an authentication token or some other identifier, look at Rails Metal Example #1: Authentication for some ideas of how to manage authentication for your API. Second, I didn’t filter any contents on the User model, so the password is passed back by the API. A simple delete call for the keys you want to omit from the hash returned by the find_by_sql call should clear up any data you don’t want to pass back.
Here’s the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # Allow the metal piece to run in isolation
require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)
class ApiHandler
def self.call(env)
req = Rack::Request.new(env)
@params = req.params
if (env["PATH_INFO"] =~ (/^\/api\/(xml|json)\/user\//)) && ApiKey.find_by_key(@params["key"]) && env["REQUEST_METHOD"] == "POST"
format = env["PATH_INFO"].split("/")[2]
return [200, {"Content-Type" => "application/xml"}, [User.find_by_sql(["SELECT * FROM users WHERE id = ?", @params["id"]]).to_xml]] if format == "xml"
[200, {"Content-Type" => "application/json"}, [User.find_by_sql(["SELECT * FROM users WHERE id = ?", @params["id"]]).to_json]] if format == "json"
else
[404, {"Content-Type" => "text/html"}, ["Not Found"]]
end
end
end |
The code here is pretty simple. You check the path to make sure it matches the api path for XML or JSON, then find the record, convert it, and send it off to the user.
A few things to note are that the Rails methods to_json and to_xml are available in Rails Metal. I also had to explicitly return on the xml format because it isn’t the last execution and therefore isn’t returned.
API, JSON, MySQL, Rails Metal, tutorial, XML
A week and a half ago, I posted 9 Ways to Use Rails Metal. The fourth way I listed was “Redirecting Affiliate Links.” The basic idea is that you can set up http://mydomain.com/hosting to go to the link you were given by the hosting company you have an affiliate account with.
The first thing I did was set up a model to manage affiliate redirects.
script/generate model affiliate_redirect path:string location:string
Then I ran my migrations, to set up the database.
Then I set up a Rails Metal instance called affiliate_redirects.
script/generate metal affiliate_redirects
From there, programming Rails Metal was pretty simple. You just have to find an AffiliateRedirect with the path visited and redirect to the AffiliateRedirect’s location. Here’s the code:
1
2
3
4
5
6
7
8
9
10
11
12
| require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)
class AffiliateRedirects
def self.call(env)
redirect = AffiliateRedirect.connection.select_all("SELECT * FROM affiliate_redirects WHERE path = '#{env["PATH_INFO"]}'").first
if redirect && (location = redirect["location"])
[302, {"Content-Type" => "text/html", "Location" => location}, ["You are being redirected."]]
else
[404, {"Content-Type" => "text/html"}, ["Not Found"]]
end
end
end |
This is the quick solution to the Rails action with nothing but a redirect_to.
middleware, Rails Metal, redirect, Ruby on Rails, tutorial
I’ve had a few requests on how to access the session from Rack and Rails Metal. In the Rack environment that is passed to the call method, the session is stored at the ‘rack.session’ index. You can use this to both read from and write to the session. Here are some examples:
1
2
| session = env['rack.session']
User.find_by_id(session["user_id"]) |
1
2
| session = env['rack.session']
session["user_id"] = 1 |
rack, Rails, Rails Metal, sessions