Sounds like a builder design pattern might work here. Have a view builder object that returns the desired behavior.
module ViewBuiler
def build(name, api_version)
View.new(name, api_version).build
end
class View < Struct(:name, :api_version)
def build
[name, api_version, 'json', 'jbuilder'].join('.')
end
end
end
and in your controller you could just do something like:
ApplicationController
include ViewBuilder
end
MyController < ApplicationController
def index
...
# you can pass either strings or symbols to build and it will
# return 'index.v1.json.jbuilder'
render build(:index, params[:api_version])
end
end
And disclaimer, this is just an idea and not something I've implemented. I like the approach for 2 reason. The Controller actions remain skinny and don't have logic in it. A builder like this seems pretty easy to test. And it keeps the thing that might change (views etc) isolated into something that can change frequently as long as it retains it's interface that the Controllers will work with.