2
\$\begingroup\$

I need to show article's content based on this logic:

  • if article's content has to be truncated (e.g for preview)
    • if there's [read more] substring in the content
      • replace first [read more] with link to the article
      • truncate content to the first occurence of [read more]
    • else
      • truncate content to the first 500 characters
  • remove all [read more] from content.

I've written a presenter for this, how can it be refactored? (_h gives access to the helpers) This is just one of the responsibilities that this presenter has, there are already a few methods (public & private), so... should I extract it into a helper?

class ArticlePresenter
  # ... omitted
  DEFAULT_LENGTH  = 500
  READ_MORE_REGEX = /\[read more\]/i

  def content(truncate)
    content = article.content
    if truncate
     index = content.index(READ_MORE_REGEX)
     if index
       url = _h.article_url(article)
       content = _h.truncate(content, length: index, omission: " [Show more](#{url})")
     else
       content = _h.truncate(content, length: DEFAULT_LENGTH)
     end
   end

   content.gsub!(READ_MORE_REGEX, '')

   html = MarkdownService.instance.render content
   content_tag :div, html
 end
\$\endgroup\$
1
\$\begingroup\$

About the naming, and grouping your code.

First improvement, change name of the variable from truncate to should_truncate, than you get

if should_truncate

instead of

if truncate

It is suggested to use methods to encapsulate code that is inside a block, for example code that is execute inside if statement, loops, or any other block of code. In your case

  def content(should_truncate)
    content = article.content
     if should_truncate
       content = truncate_article_content
     end
     content.gsub!(READ_MORE_REGEX, '')

     html = MarkdownService.instance.render content
     content_tag :div, html
  end

private

  def truncate_article_content
    index_at = article.content.index(READ_MORE_REGEX)
    if index_at
      truncate_length index_at
    else
      first_characters
    end
  end

  def truncate_length(length)
    url = _h.article_url(article)
    _h.truncate(article.content, length: length, omission: " [Show more](#{url})")
  end

  def first_characters(length= DEFAULT_LENGTH)
    _h.truncate(article.content, length: length)
  end
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.