0

Working on an assignment here. Was just introduced to Redcarpet and the Markdown conversion Method.

This was placed inside my Helper:

def markdown_to_html(markdown)
  renderer = Redcarpet::Render::HTML.new
  extensions = { fenced_code_blocks: true }
  redcarpet = Redcarpet::Markdown.new(renderer, extensions)
  (redcarpet.render markdown).html_safe
end

And I could call the method in my views like so:

views/posts/show.html.erb:

<h1><%= markdown_to_html @post.title %></h1>

<div class="row">
  <div class="col-md-8">
    <p><%= markdown_to_html @post.body %>
  </div>
  <div class="col-md-4">
    <% if policy(@post).edit? %>
      <%= link_to "Edit", edit_topic_post_path(@topic, @post), class: 'btn btn-success' %>
    <% end %>
  </div>
</div>

Now I have to do the following:

The goal is to render markdown like so:

<%= post.markdown_title %>
<%= post.markdown_body %>

Add Post#markdown_title and Post#markdown_body to Post:

Create a private Post#render_as_markdown method that markdown_title and markdown_body can call. This will keep the markdown_title and markdown_body DRY.

Remove the markdown_to_html method from application_helper.rb.

Update your views to use the Post#markdown_title and Post#markdown_body methods.

I have so far attempted to do this:

models/post.rb:

class Post < ActiveRecord::Base
  has_many :comments
  belongs_to :user
  belongs_to :topic

  # Sort by most recent posts first
  default_scope { order('created_at DESC') }

  # Post must have at least 5 characters in the title
  validates :title, length: { minimum: 5 }, presence: true
  # Post must have at least 20 characters in the body
  validates :body, length: { minimum: 20 }, presence: true
  # Post must have an associated topic and user
  validates :topic, presence: true
  validates :user, presence: true

  def render_as_markdown(markdown)
    renderer = Redcarpet::Render::HTML.new
    extensions = { fenced_code_blocks: true }
    redcarpet = Redcarpet::Markdown.new(renderer, extensions)
    (redcarpet.render markdown).html_safe
  end

  private 

  def markdown_title(markdown)
    render_as_markdown(markdown).title
  end

  def markdown_body(markdown)
    render_as_markdown(markdown).body
  end
end

If we go back to my views/posts/show.html.erb:

<h1><%= @post.title.markdown_title %></h1>

Will render:

NoMethodError in Posts#show

undefined method `markdown_title' for "chopper mag":String
Extracted source (around line #1):

<h1><%= @post.title.markdown_title %></h1>

<div class="row">
  <div class="col-md-8">
    <p><%= markdown_to_html @post.body %>
  </div>

What am I doing wrong and how can I rectify this issue?

Thanks kindly.

Joe Kennedy
  • 9,365
  • 7
  • 41
  • 55
Jonathan Musso
  • 1,374
  • 3
  • 21
  • 45

1 Answers1

2

A few things here. First, you've made markdown_title a private method in your class, so it won't be accessible in your view. You need to remove the word private from above your markdown_title and markdown_body methods in order to make them available to your views. In addition, since the requirement is to make render_as_markdown private, you need to move that below the private keyword. Long story short, your methods should be structured in your class as follows:

def markdown_title(markdown)
  ...
end

def markdown_body(markdown)
  ...
end

private 

def render_as_markdown(markdown)
  ...
end

Second, if you take a look at how markdown_title and markdown_body are supposed to be called (below), they don't take in any parameters.

<%= post.markdown_title %>
<%= post.markdown_body %>

So, your Post object methods markdown_title and markdown_body shouldn't take in any parameters. And since they are called on a specific object of class Post, they don't need to take in any.

def markdown_title
  render_as_markdown(self.title)
end

def markdown_body
  render_as_markdown(self.body)
end

Then, in your view, you can use markdown_title and markdown_body according to the requirements:

<h1><%= @post.markdown_title %></h1>

<div class="row">
  <div class="col-md-8">
    <p><%= @post.markdown_body %>
  </div>
  ...
</div>
Joe Kennedy
  • 9,365
  • 7
  • 41
  • 55
  • Thank you kindly for your explanation on what I was doing wrong and how it was supposed to be. This worked perfectly. Cheers! – Jonathan Musso May 06 '15 at 20:33