Before going any further, I have googled this. I do know the arguments for why you shouldn't have url_for located in the model as this seemingly violates the MVC paradigm. In this instance I disagree as this is functioning more as an API for some resources, rather than as a UI.
I have created a custom responder, and am returning a JSON object which looks like this per request:
obj = {
json: resource.as_json,
request_url: params[:id] ? resource_url : collection_url,
partial: get_partial(:partial, options),
flash: flash,
flash_par开发者_StackOverflow社区tial: get_partial(:flash, options),
user: @current_user,
status: response.status,
}
I want each of the objects the controller responds with (using respond_with) to have a url enclosed so that on the client side I can easily keep track of where to send additional requests for a given object (in this case grabbing different view representations depending on which widget has subscribed to that object's state).
I think the best way to to do this is on the model side, as that seems to be the way Rails wants it. Simply adding a function with the url, and then using as_json(:methods => :url). Unfortunately, url_for is not available on the model side, and I haven't been able to find a Rails3.1 compatible way of including it into ActiveRecord::Base.
class << ActiveRecord::Base
def url
url_for self
end
end
Model.new.as_json(:includes => :url)
I'm open to alternative suggestions as well.
This seems to work... It's a bit of a hack IMO:
class << ActiveRecord::Base
include Rails.application.routes.url_helpers
include ActionDispatch::Routing::UrlFor
def default_url_options
{ :host => 'localhost:3000' }
end
def url
url_for(self)
end
def as_json options
super options.merge(:methods => :url)
end
end
精彩评论