Skip to content

Instantly share code, notes, and snippets.

@seancribbs
Forked from jamis/assets_resource.rb
Created October 23, 2011 14:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seancribbs/1307440 to your computer and use it in GitHub Desktop.
Save seancribbs/1307440 to your computer and use it in GitHub Desktop.
Sprockets asset resource for Webmachine (asset pipelining!)
class Resources::Assets < Webmachine::Resource
def content_types_provided
path = request.uri.path
@asset = Application.assets[path]
if @asset.present?
[[@asset.content_type, :to_asset]]
else
# Better to simply provide a content-type you CAN provide, even if it's not acceptable.
# Since the asset is not there, it'll bail anyway at resource_exists?
[["text/html", :to_html]]
end
end
def resource_exists?
@asset.present?
end
def generate_etag
@asset.digest
end
def last_modified
@asset.mtime
end
def to_asset
@asset.to_s
end
def to_html
Application.logger.error "reached impossible state in asset resource (no asset, but no error) path=#{request.path_tokens.inspect}"
"<html><body><h1>Bug!</h1><p>Shouldn't ever get here.</p></body></html>"
end
end
@jamis
Copy link

jamis commented Oct 23, 2011

Thanks for taking a look at this! Good to know about "request.uri.path", I didn't make the connection that uri was an actual URI object. :)

The problem with [["text/html", :to_html]] is that if the asset doesn't exist, and "text/html" wasn't what the client requested, it'll fail with a 406. I'd rather it failed with a 404, so in my version I force it to be acceptable by using the first content-type in the Accept header, whatever that happens to be. It doesn't really matter what it accepts, because as you said, it'll fail at resource_exists, which is the point.

It's kind of a hack, but it's not something most resources need to deal with, anyway.

@seancribbs
Copy link
Author

Yeah, it's interesting because content_types_provided happens much earlier than resource_exists? (and is called many times). Another option might be to use one of the halt-able callbacks (service_available? comes to mind) to simply return a 404.

@jamis
Copy link

jamis commented Oct 23, 2011

Ah, interesting approach. I'm still learning my way around the callbacks, but I'll try experimenting with service_available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment