views:

110

answers:

1

I am new to Rails but have used PHP extensively over the years. I am building a simple blog (I know) to get my skills up in the MVC/Rails world.

I have the basics working but have spent the weekend trying to get Maruku to work eg a post body saved from a text area with Markdown Extra markup to the db and then back again to the browser.

I used the following code in my Post model but I get an error when I try to load /posts - "undefined local variable or method `maruku' for #"

class Post < ActiveRecord::Base
validates :name,  :presence => true
validates :title, :presence => true,
                :length => { :minimum => 5 }
validates :content,  :presence => true
validates :excerpt,  :presence => true

has_many :comments, :dependent => :destroy

maruku.new(:content).to_html

end

I also tried something similar in my Posts Controller that I found on here. Then called @post.content in my Show view but get an error:

body = maruku.new(post.body)
post.body = body.to_html

I am dead sure it's my noob brain being dead but any help or direction would be great as I have fought with this for two days now. BTW I am using maruku as I need Markdown Extra as my old blog posts are all formatted that way.

Thanks

UPDATED - PostsController

class PostsController < ApplicationController

# GET /posts
# GET /posts.xml
def index
@posts = Post.find(:all, :order => 'created_at DESC')

respond_to do |format|
format.html # index.html.erb
format.xml  { render :xml => @posts }
end
end

# GET /posts/1
# GET /posts/1.xml
def show
@post = Post.find(params[:id])

respond_to do |format|
format.html # show.html.erb
format.xml  { render :xml => @post }
end
end

# GET /posts/new
# GET /posts/new.xml
def new
@post = Post.new

respond_to do |format|
format.html # new.html.erb
format.xml  { render :xml => @post }
end
end

# GET /posts/1/edit
def edit
@post = Post.find(params[:id])
end


# POST /posts
# POST /posts.xml
def create
@post = Post.new(params[:post])

respond_to do |format|
if @post.save
format.html { redirect_to(@post, :notice => 'Post was successfully created.') }
format.xml  { render :xml => @post, :status => :created, :location => @post }
else
format.html { render :action => "new" }
format.xml  { render :xml => @post.errors, :status => :unprocessable_entity }
end
end
end

# PUT /posts/1
# PUT /posts/1.xml
def update
@post = Post.find(params[:id])

respond_to do |format|
if @post.update_attributes(params[:post])
format.html { redirect_to(@post, :notice => 'Post was successfully updated.') }
format.xml  { head :ok }
else
format.html { render :action => "edit" }
format.xml  { render :xml => @post.errors, :status => :unprocessable_entity }
end
end
end

# DELETE /posts/1
# DELETE /posts/1.xml
def destroy
@post = Post.find(params[:id])
@post.destroy

respond_to do |format|
format.html { redirect_to(posts_url) }
format.xml  { head :ok }
end
end
end
A: 

You need to use (note the case):

Maruku.new(...)

Constants in ruby begin in an upper case letter and variables begin in a lower case letter (you are accessing a class, which is a constant).

Also, ensure that you include the gem in your Gemfile (Rails 3 requires all libraries be specified in this file).

Finally, you can not use Maruku as you listed. Instead, try:

class Post < ActiveRecord::Base

  ...

  def content_html
      Maruku.new(self.content).to_html    
  end

end

Then in your view, you can access through <%= @post.content_html %>. Note, you should probably do a conversion to HTML using a callback (see Active Record Callbacks) for improved performance at some point, but this should get you up and running.

Kevin Sylvestre
Thanks really appreciate the help - wasn't aware of that. I made the changes but now get a "NoMethodError in PostsController#index" error with the next line saying "private method `gsub' called for :content:Symbol"
rollbahn
@rollbahn Update your sample code.
Kevin Sylvestre
Not sure how to update the code in a comment as it doesn't seem to parse properly? class Post < ActiveRecord::Base validates :name, :presence => true validates :title, :presence => true, :length => { :minimum => 5 } validates :content, :presence => true validates :excerpt, :presence => true has_many :comments, :dependent => :destroy Maruku.new(:content).to_html end
rollbahn
Just update your original post...
Kevin Sylvestre
Also, need the section of the code where the error is occurring (your controller).
Kevin Sylvestre
All updated - thanks for your patience
rollbahn
You need to remove the line "Maruku.new(:content).to_html" from your controller. You cannot add random code snippets to a class (they need to be contained within a method. I updated my code above with more details.
Kevin Sylvestre
Thanks very much that is now getting the Markdown conversion on the fly in the Show view eg What is stored in the db in Markdown is showing with HTML markup onscreen, which shows it can work but needs to render as HTML rather than showing it onscreen as markup.So I am thinking that to get the HTML to render on screen rather than seeing the markup itself I would need to be doing the conversion in the "def show" part of the controller? Perhaps before or after "@post = Post.find(params[:id])"?
rollbahn
This sounds like an issue with Rails 3 escaping HTML. See: http://asciicasts.com/episodes/204-xss-protection-in-rails-3. Specifically, call 'html_safe' on your output. That is: 'Maruku.new(:content).to_html.html_safe'.
Kevin Sylvestre
Awesome thanks so much that works! Never would have thought of that as the issue.
rollbahn
So is this answered?
Kevin Sylvestre