2

I'm using Rails as a REST server, and one of my models has a description field. In that model's JSON representation, I need to output both the regular description field AND an arbitrary non-DB attribute called description_markdown that is just the description run through a markdown filter. I already know how to run text through markdown using redcarpet, like:

@post = Post.find(params[:id])
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :autolink => true, :space_after_headers => true, :fenced_code_blocks => true, :lax_html_blocks => true)
description_markdown = markdown.render(@post.description).html_safe

But what I really need is to make description_markdown an attribute on @post (like @post.description_markdown), and have it output in @post's JSON representation.

3 Answers 3

4

I normally use RABL gem to build JSON views for my APIs -- it gives you a lot of flexibility on building JSON responses, such as creating custom child nodes, adding arbitrary code. Check it out. But, to answer your question, you can probably overwrite as_json method of Post to include the return of description_markdown. Something like (not tested):

#post.rb
class Post < ActiveRecord::Base

  def description_markdown
    ...
  end
  ...
  def as_json(options)
    super(:only => [:attributes_you_want], :methods => [:description_markdown])
  end
  ...
end

Then, in controller:

render :json => @post

Hope, it helps.

Sign up to request clarification or add additional context in comments.

Comments

2

You could add description_markdown to your model:

def description_markdown
    markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :autolink => true, :space_after_headers => true, :fenced_code_blocks => true, :lax_html_blocks => true)
    markdown.render(description).html_safe
end

Then add that to your model's as_json using :methods:

def as_json(options = { })
    super((options || { }).merge({
        :methods => [:description_markdown]
    }))
end

That would add your description_markdown output to your model's standard JSON representation. The options || { } is there in case someone hands you a nil for options, then we merge our :methods into the options, and hand it off to ActiveRecord::Base for the heavy lifting. You'll need more complicated merging for options if you want outsiders to be able to send in their own :methods values.

Comments

0

Just wanted to add an alternative in case you're defining what fields/data you need in the controller (like you might in a Rails 4 app), like so:

Post.to_json(only: [], methods: [:generate_markdown])

in your Post code, add:

def generate_markdown
    markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :autolink => true, :space_after_headers => true, :fenced_code_blocks => true, :lax_html_blocks => true)
    return markdown.render(@post.description).html_safe

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.