> rails g scaffold snippet caption:string content:text language:string section_id:integer
db/migrate/2010…_create_snippets.rb
t.string :language, default: 'ruby'
def change
create_table :snippets do |t|
t.string :caption
t.text :content
t.string :language, default: 'ruby'
t.integer :section_id
t.timestamps
end
end
end
app/models/snippet.rb
class Snippet < ActiveRecord::Base
belongs_to :section
validates :caption, :presence => true
validates :content, :presence => true
def post_sequence
section.post.sequence if section.post
end
end
app/models/section.rb
class Section < ActiveRecord::Base
...
has_one :snippet, :dependent => :destroy
accepts_nested_attributes_for :snippet, :reject_if => lambda{ |a| a[:content].blank? && a[:caption].blank? }
...
end
app/views/posts/_form.html.haml
= snippet_f.input :language, :as => :select, :collection => coderay_languages
= simple_form_for(@post) do |f|
= render 'shared/error_messages', :target => @post
.inputs
...
= f.simple_fields_for :sections do |section_f|
.section
...
= section_f.simple_fields_for :snippet do |snippet_f|
.snippet
%h3 Snippet
= snippet_f.input :caption, :required => false
= snippet_f.input :content, :input_html => {:rows =>5}, :required => false
= snippet_f.input :language, :as => :select, :collection => coderay_languages
%hr
# Gemfile
gem 'coderay'
_________________
# Terminal
> bundle install
app/helpers/application_helper.rb
CodeRay.scan(text, lang).div(
def coderay(text, lang)
CodeRay.scan(text, lang).div(
:css => :class,
:tab_width => 2)
end
def coderay_languages
Hash[*CODERAY_LANGUAGES.map {|l| [l.humanize, l] }.flatten]
end
end
config/initializers/constants.rb
CODERAY_LANGUAGES = ["css", "html", "java_script", "json",
"ruby", "sql", "xhtml", "yaml"]
app/models/post.rb and app/controllers/posts_controller.rb
# post.rb
class Post < ActiveRecord::Base
...
def build_section_and_snippet
sections.build if sections.empty?
sections.each{ |section| section.build_snippet if section.snippet.nil?}
end
end
________________________________
# posts_controller.rb
class PostsController < ApplicationController
...
def new
@post = Post.new(:sequence => Post.count + 1)
@post.build_section_and_snippet
end
def edit
@post = Post.find(params[:id])
@post.build_section_and_snippet
end
end
app/models/post.rb
class Post < ActiveRecord::Base
...
accepts_nested_attributes_for :sections,
:reject_if => proc { |attr| attr['heading'].blank? && attr['body'].blank? }