I was going into a project to do some general code refactoring (it’s a hobby, you know), and found some tests that we’re failing. Figured I’d fix those first and then bitch at whoever left failing tests in a project later. One test failure in particular looked a bit odd to me…
1) Error:
test: The 'Add to Web' form should pass a URL into the form. (LettucesControllerTest):
ActionView::TemplateError: undefined method `rewrite' for "http://mocked.com":String
On line #1 of layouts/_footer.html.erb
1: <%= link_to 'Privacy Policy', privacy_policy_path %>
2: <%= link_to 'Terms & Conditions', terms_path %>
3: <%= link_to 'Contact Us', site_contact_path %>
(eval):15
app/views/layouts/_footer.html.erb:1
…that’s interesting, I thought. What the hell does “http://mocked.com” have to do with anything in that line? Well the functional test looked like this…
setup do
login_as :activated_user
get :new, :url => "http://mocked.com"
end
…and the action in the controller looked like this…
# User added lettuces page, scrapes lettuce URL if given for suggested title and images
def new
@url = params[:url]
@lettuce = @url.blank? ? Lettuce.new : Lettuce.from_url(@url)
end

So, ok – it looks like an external site can pass a “url” param in via the url, to indicate which page this action should reach out to and scrape for Lettuce content. I removed the @url assignment line from the action and put a <%=h @url.class %> and and <%=h @url.methods.sort %> into the ‘new’ view file and loaded that in my browser.
Sure enough — @url is an ActionController::UrlRewriter, and it has a #rewrite method, amongst some other things. I’m guessing that rails routing is using this somewhere, but I’m not curious to go find out because it will delay my refactoring mission.
Now, thankfully I didn’t like that there was an instance variable named @url in the first place, since it was being created only for the purpose of letting the view use an instance variable instead of accessing #params directly. However, there was a conditional case in the view for how to handle a #blank? url vs a non blank url, so it had to be available to the view somehow. I refactored to…
def new
@lettuce = requested_lettuce_url.blank? ? Lettuce.new : Lettuce.from_url(requested_lettuce_url)
end
protected
helper_method :requested_lettuce_url
def requested_lettuce_url
params[:url] || ''
end
And now…
Now that the lettuces_controller is looking good, I can start working on the meats_controller and see what it has in store.