comfy_blog 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +11 -0
- data/LICENSE +20 -0
- data/README.md +23 -0
- data/Rakefile +21 -0
- data/VERSION +1 -0
- data/app/assets/images/rails.png +0 -0
- data/app/assets/javascripts/application.js +8 -0
- data/app/assets/stylesheets/comfy_blog/admin.css +57 -0
- data/app/assets/stylesheets/comfy_blog/application.css +73 -0
- data/app/assets/stylesheets/comfy_blog/reset.css +1 -0
- data/app/controllers/application_controller.rb +5 -0
- data/app/controllers/blog/admin/base_controller.rb +3 -0
- data/app/controllers/blog/admin/comments_controller.rb +34 -0
- data/app/controllers/blog/admin/posts_controller.rb +57 -0
- data/app/controllers/blog/posts_controller.rb +33 -0
- data/app/helpers/blog/application_helper.rb +16 -0
- data/app/models/.gitkeep +0 -0
- data/app/models/blog/comment.rb +21 -0
- data/app/models/blog/post.rb +81 -0
- data/app/models/blog/tag.rb +25 -0
- data/app/models/blog/tagging.rb +22 -0
- data/app/views/blog/admin/_html_head.html.erb +1 -0
- data/app/views/blog/admin/_navigation.html.erb +1 -0
- data/app/views/blog/admin/comments/_comment.html.erb +22 -0
- data/app/views/blog/admin/comments/destroy.js.erb +3 -0
- data/app/views/blog/admin/comments/index.html.erb +10 -0
- data/app/views/blog/admin/comments/publish.js.erb +1 -0
- data/app/views/blog/admin/posts/_form.html.erb +24 -0
- data/app/views/blog/admin/posts/_post.html.erb +21 -0
- data/app/views/blog/admin/posts/edit.html.erb +5 -0
- data/app/views/blog/admin/posts/index.html.erb +9 -0
- data/app/views/blog/admin/posts/new.html.erb +5 -0
- data/app/views/blog/posts/_post.html.erb +18 -0
- data/app/views/blog/posts/index.html.erb +5 -0
- data/app/views/blog/posts/show.html.erb +1 -0
- data/app/views/layouts/application.html.erb +17 -0
- data/comfy_blog.gemspec +125 -0
- data/config.ru +4 -0
- data/config/application.rb +48 -0
- data/config/boot.rb +6 -0
- data/config/database.yml +25 -0
- data/config/environment.rb +5 -0
- data/config/environments/development.rb +33 -0
- data/config/environments/production.rb +51 -0
- data/config/environments/test.rb +42 -0
- data/config/initializers/comfy_blog.rb +18 -0
- data/config/initializers/secret_token.rb +3 -0
- data/config/initializers/wrap_parameters.rb +14 -0
- data/config/locales/en.yml +5 -0
- data/config/routes.rb +29 -0
- data/db/migrate/01_create_comfy_blog.rb +55 -0
- data/db/schema.rb +63 -0
- data/db/seeds.rb +7 -0
- data/lib/comfy_blog.rb +26 -0
- data/lib/comfy_blog/configuration.rb +33 -0
- data/lib/comfy_blog/core_ext/string.rb +8 -0
- data/lib/comfy_blog/engine.rb +20 -0
- data/lib/comfy_blog/form_builder.rb +50 -0
- data/lib/generators/README +10 -0
- data/lib/generators/blog_generator.rb +31 -0
- data/script/rails +6 -0
- data/test/fixtures/.gitkeep +0 -0
- data/test/fixtures/blog/comments.yml +6 -0
- data/test/fixtures/blog/posts.yml +8 -0
- data/test/fixtures/blog/taggings.yml +7 -0
- data/test/fixtures/blog/tags.yml +9 -0
- data/test/functional/.gitkeep +0 -0
- data/test/functional/blog/admin/comments_controller_test.rb +38 -0
- data/test/functional/blog/admin/posts_controller_test.rb +100 -0
- data/test/functional/blog/posts_controller_test.rb +93 -0
- data/test/test_helper.rb +40 -0
- data/test/unit/.gitkeep +0 -0
- data/test/unit/comment_test.rb +34 -0
- data/test/unit/configuration_test.rb +19 -0
- data/test/unit/post_test.rb +121 -0
- data/test/unit/tag_test.rb +44 -0
- data/test/unit/tagging_test.rb +30 -0
- metadata +172 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Oleg Khabarov, The Working Group
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# ComfyBlog
|
2
|
+
|
3
|
+
ComfyBlog is an simple blog management engine for Rails 3.1 apps. As a bonus it integrates seamlessly with [ComfortableMexicanSofa](https://github.com/comfy/comfortable-mexican-sofa) CMS Engine
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add gem definition to your Gemfile:
|
8
|
+
|
9
|
+
gem 'comfy_blog'
|
10
|
+
|
11
|
+
Then from the Rails project's root run:
|
12
|
+
|
13
|
+
bundle install
|
14
|
+
rails g blog
|
15
|
+
rake db:migrate
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
TODO
|
20
|
+
|
21
|
+
Sofa Blog is released under the [MIT license](https://github.com/comfy/comfy-blog/raw/master/LICENSE)
|
22
|
+
|
23
|
+
Copyright 2011 Oleg Khabarov, [The Working Group Inc](http://www.twg.ca)
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.expand_path('../config/application', __FILE__)
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rake'
|
4
|
+
|
5
|
+
ComfyBlog::Application.load_tasks
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'jeweler'
|
9
|
+
Jeweler::Tasks.new do |gem|
|
10
|
+
gem.name = 'comfy_blog'
|
11
|
+
gem.homepage = 'http://github.com/comfy/comfy-blog'
|
12
|
+
gem.license = 'MIT'
|
13
|
+
gem.summary = 'ComfyBlog is a blog engine for Rails 3.1 apps (and ComfortableMexicanSofa)'
|
14
|
+
gem.description = ''
|
15
|
+
gem.email = 'oleg@twg.ca'
|
16
|
+
gem.authors = ['Oleg Khabarov', 'The Working Group Inc.']
|
17
|
+
end
|
18
|
+
Jeweler::GemcutterTasks.new
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
21
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
Binary file
|
@@ -0,0 +1,8 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into including all the files listed below.
|
2
|
+
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
|
3
|
+
// be included in the compiled file accessible from http://example.com/assets/application.js
|
4
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
5
|
+
// the compiled file.
|
6
|
+
//
|
7
|
+
//= require jquery
|
8
|
+
//= require jquery_ujs
|
@@ -0,0 +1,57 @@
|
|
1
|
+
/* === List items === */
|
2
|
+
ul.list.posts li .item .label,
|
3
|
+
ul.list.comments li .item .label {
|
4
|
+
margin-left: 0px ! important;
|
5
|
+
}
|
6
|
+
ul.list.comments li .item .label .sublabel em {
|
7
|
+
margin-left: 5px;
|
8
|
+
}
|
9
|
+
ul.list.comments li .item .content {
|
10
|
+
font-size: 11px;
|
11
|
+
font-weight: normal;
|
12
|
+
margin: 5px 0px 0 35px;
|
13
|
+
}
|
14
|
+
|
15
|
+
/* === Tags === */
|
16
|
+
span.tag {
|
17
|
+
font-size: 10px;
|
18
|
+
padding: 1px 5px;
|
19
|
+
background-color: #d5d5d5;
|
20
|
+
border-radius: 2px;
|
21
|
+
-moz-border-radius: 2px;
|
22
|
+
}
|
23
|
+
|
24
|
+
|
25
|
+
/* === Autocomplete === */
|
26
|
+
.ac_results {
|
27
|
+
padding: 0px;
|
28
|
+
border: 1px solid #999;
|
29
|
+
background-color: white;
|
30
|
+
overflow: hidden;
|
31
|
+
z-index: 99999;
|
32
|
+
color: #666;
|
33
|
+
}
|
34
|
+
.ac_results ul {
|
35
|
+
width: 100%;
|
36
|
+
list-style-position: outside;
|
37
|
+
list-style: none;
|
38
|
+
padding: 0;
|
39
|
+
margin: 0;
|
40
|
+
}
|
41
|
+
.ac_results ul li {
|
42
|
+
margin: 0px;
|
43
|
+
padding: 2px 5px;
|
44
|
+
cursor: default;
|
45
|
+
display: block;
|
46
|
+
font-size: 12px;
|
47
|
+
line-height: 16px;
|
48
|
+
overflow: hidden;
|
49
|
+
}
|
50
|
+
|
51
|
+
.ac_odd {
|
52
|
+
background-color: #eee;
|
53
|
+
}
|
54
|
+
.ac_over {
|
55
|
+
background-color: #C4EAF6;
|
56
|
+
color: #000;
|
57
|
+
}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
/*
|
2
|
+
= require ./reset
|
3
|
+
= require_self
|
4
|
+
*/
|
5
|
+
|
6
|
+
body {
|
7
|
+
padding: 25px;
|
8
|
+
font: 13px/18px Arial, sans-serif;
|
9
|
+
}
|
10
|
+
h1 {
|
11
|
+
font: bold 26px/34px Arial, sans-serif;
|
12
|
+
margin-bottom: 15px;
|
13
|
+
}
|
14
|
+
h2 {
|
15
|
+
font: bold 18px/20px Arial, sans-serif;
|
16
|
+
margin-bottom: 10px;
|
17
|
+
}
|
18
|
+
a {
|
19
|
+
color: #3875D7;
|
20
|
+
text-decoration: none;
|
21
|
+
}
|
22
|
+
a:hover {
|
23
|
+
text-decoration: underline;
|
24
|
+
}
|
25
|
+
table.formatted td,
|
26
|
+
table.formatted th {
|
27
|
+
padding: 2px 5px;
|
28
|
+
border-bottom: 1px dotted #ccc;
|
29
|
+
}
|
30
|
+
table.formatted th {
|
31
|
+
background-color: #666;
|
32
|
+
color: #fff;
|
33
|
+
}
|
34
|
+
table.formatted td img {
|
35
|
+
float: left;
|
36
|
+
padding: 2px;
|
37
|
+
margin-right: 2px;
|
38
|
+
}
|
39
|
+
table.formatted td .sublabel {
|
40
|
+
font-size: 11px;
|
41
|
+
line-height: 11px;
|
42
|
+
color: #888;
|
43
|
+
}
|
44
|
+
|
45
|
+
.form_element {
|
46
|
+
overflow: hidden;
|
47
|
+
margin-bottom: 5px;
|
48
|
+
}
|
49
|
+
.form_element .label {
|
50
|
+
width: 125px;
|
51
|
+
float: left;
|
52
|
+
text-align: right;
|
53
|
+
}
|
54
|
+
.form_element .value,
|
55
|
+
.form_element .errors {
|
56
|
+
margin-left: 135px;
|
57
|
+
}
|
58
|
+
.form_element .value input[type='text'],
|
59
|
+
.form_element .value textarea {
|
60
|
+
width: 400px;
|
61
|
+
}
|
62
|
+
|
63
|
+
.jcrop-holder {
|
64
|
+
margin-bottom: 15px;
|
65
|
+
}
|
66
|
+
|
67
|
+
.flash{
|
68
|
+
border: 2px solid #ccc;
|
69
|
+
padding: 10px;
|
70
|
+
margin-bottom: 15px;
|
71
|
+
text-align: center;
|
72
|
+
}
|
73
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit;}del,ins{text-decoration:none;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:baseline;}sub{vertical-align:baseline;}legend{color:#000;}input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Blog::Admin::CommentsController < Blog::Admin::BaseController
|
2
|
+
|
3
|
+
before_filter :load_post, :only => [:index]
|
4
|
+
before_filter :load_comment, :only => [:destroy, :publish]
|
5
|
+
|
6
|
+
def index
|
7
|
+
@comments = @post ? @post.comments : Blog::Comment.all
|
8
|
+
end
|
9
|
+
|
10
|
+
def destroy
|
11
|
+
@comment.destroy
|
12
|
+
end
|
13
|
+
|
14
|
+
def publish
|
15
|
+
@comment.update_attribute(:is_published, true)
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def load_post
|
21
|
+
return unless params[:post_id]
|
22
|
+
@post = Blog::Post.find(params[:post_id])
|
23
|
+
rescue ActiveRecord::RecordNotFound
|
24
|
+
flash[:error] = 'Blog Post not found'
|
25
|
+
redirect_to :action => :index
|
26
|
+
end
|
27
|
+
|
28
|
+
def load_comment
|
29
|
+
@comment = Blog::Comment.find(params[:id])
|
30
|
+
rescue ActiveRecord::RecordNotFound
|
31
|
+
# ... do nothing
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class Blog::Admin::PostsController < Blog::Admin::BaseController
|
2
|
+
|
3
|
+
before_filter :build_post, :only => [:new, :create]
|
4
|
+
before_filter :load_post, :only => [:edit, :update, :destroy]
|
5
|
+
|
6
|
+
def index
|
7
|
+
@posts = Blog::Post.paginate :page => params[:page]
|
8
|
+
end
|
9
|
+
|
10
|
+
def new
|
11
|
+
render
|
12
|
+
end
|
13
|
+
|
14
|
+
def create
|
15
|
+
@post.save!
|
16
|
+
flash.now[:notice] = 'Blog Post created'
|
17
|
+
render :action => :new
|
18
|
+
|
19
|
+
rescue ActiveRecord::RecordInvalid
|
20
|
+
flash.now[:error] = 'Failed to create Blog Post'
|
21
|
+
render :action => :new
|
22
|
+
end
|
23
|
+
|
24
|
+
def edit
|
25
|
+
render
|
26
|
+
end
|
27
|
+
|
28
|
+
def update
|
29
|
+
@post.update_attributes!(params[:post])
|
30
|
+
flash.now[:notice] = 'Blog Post updated'
|
31
|
+
render :action => :edit
|
32
|
+
|
33
|
+
rescue ActiveRecord::RecordInvalid
|
34
|
+
flash.now[:error] = 'Failed to update Blog Post'
|
35
|
+
render :action => :edit
|
36
|
+
end
|
37
|
+
|
38
|
+
def destroy
|
39
|
+
@post.destroy
|
40
|
+
flash[:notice] = 'Blog Post removed'
|
41
|
+
redirect_to :action => :index
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def load_post
|
47
|
+
@post = Blog::Post.find(params[:id])
|
48
|
+
rescue ActiveRecord::RecordNotFound
|
49
|
+
flash[:error] = 'Blog Post not found'
|
50
|
+
redirect_to :action => :index
|
51
|
+
end
|
52
|
+
|
53
|
+
def build_post
|
54
|
+
@post = Blog::Post.new(params[:post])
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Blog::PostsController < ApplicationController
|
2
|
+
|
3
|
+
layout ComfyBlog.config.public_layout
|
4
|
+
|
5
|
+
def index
|
6
|
+
scope = if params[:tag]
|
7
|
+
Blog::Post.published.tagged_with(params[:tag])
|
8
|
+
elsif params[:category]
|
9
|
+
Blog::Post.published.categorized_as(params[:category])
|
10
|
+
elsif params[:year]
|
11
|
+
scope = Blog::Post.published.for_year(params[:year])
|
12
|
+
params[:month] ? scope.for_month(params[:month]) : scope
|
13
|
+
else
|
14
|
+
Blog::Post.published
|
15
|
+
end
|
16
|
+
|
17
|
+
@posts = scope.paginate :per_page => ComfyBlog.config.posts_per_page, :page => params[:page]
|
18
|
+
end
|
19
|
+
|
20
|
+
def show
|
21
|
+
@post = if params[:slug] && params[:year] && params[:month]
|
22
|
+
Blog::Post.published.find_by_year_and_year_and_slug!(params[:year], params[:month], params[:slug])
|
23
|
+
else
|
24
|
+
Blog::Post.published.find(params[:id])
|
25
|
+
end
|
26
|
+
rescue ActiveRecord::RecordNotFound
|
27
|
+
if defined? ComfortableMexicanSofa
|
28
|
+
render :cms_page => '/404', :status => 404
|
29
|
+
else
|
30
|
+
render :text => 'Post not found', :status => 404
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Blog::ApplicationHelper
|
2
|
+
|
3
|
+
def comfy_blog_form_for(record_or_name_or_array, *args, &proc)
|
4
|
+
options = args.extract_options!
|
5
|
+
form_for(
|
6
|
+
record_or_name_or_array,
|
7
|
+
*(args << options.merge(:builder => ComfyBlog.config.form_builder.to_s.constantize)),
|
8
|
+
&proc
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
def blog_post_path(post)
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
data/app/models/.gitkeep
ADDED
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Blog::Comment < ActiveRecord::Base
|
2
|
+
|
3
|
+
set_table_name :blog_comments
|
4
|
+
|
5
|
+
attr_accessible :author,
|
6
|
+
:email,
|
7
|
+
:content
|
8
|
+
|
9
|
+
# -- Relationships --------------------------------------------------------
|
10
|
+
belongs_to :post
|
11
|
+
|
12
|
+
# -- Validations ----------------------------------------------------------
|
13
|
+
validates :post_id, :content, :author, :email,
|
14
|
+
:presence => true
|
15
|
+
validates :email,
|
16
|
+
:format => { :with => /^([\w.%-+]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i }
|
17
|
+
|
18
|
+
# -- Scopes ---------------------------------------------------------------
|
19
|
+
scope :published, where(:is_published => true)
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
class Blog::Post < ActiveRecord::Base
|
2
|
+
|
3
|
+
set_table_name :blog_posts
|
4
|
+
|
5
|
+
# -- Attributes -----------------------------------------------------------
|
6
|
+
attr_accessor :tag_names,
|
7
|
+
:category_ids
|
8
|
+
|
9
|
+
# -- Relationships --------------------------------------------------------
|
10
|
+
has_many :comments, :dependent => :destroy
|
11
|
+
has_many :taggings, :dependent => :destroy
|
12
|
+
has_many :tags, :through => :taggings
|
13
|
+
|
14
|
+
# -- Validations ----------------------------------------------------------
|
15
|
+
validates :title, :slug, :year, :month, :content,
|
16
|
+
:presence => true
|
17
|
+
validates :slug,
|
18
|
+
:uniqueness => { :scope => [:year, :month] }
|
19
|
+
|
20
|
+
# -- Scopes ---------------------------------------------------------------
|
21
|
+
default_scope order('created_at DESC')
|
22
|
+
|
23
|
+
scope :published, where(:is_published => true)
|
24
|
+
scope :for_year, lambda { |year|
|
25
|
+
where(:year => year)
|
26
|
+
}
|
27
|
+
scope :for_month, lambda { |month|
|
28
|
+
where(:month => month)
|
29
|
+
}
|
30
|
+
scope :tagged_with, lambda { |tag|
|
31
|
+
joins(:tags).where('blog_tags.name' => tag, 'blog_tags.is_category' => false)
|
32
|
+
}
|
33
|
+
scope :categorized_as, lambda { |tag|
|
34
|
+
joins(:tags).where('blog_tags.name' => tag, 'blog_tags.is_category' => true)
|
35
|
+
}
|
36
|
+
|
37
|
+
# -- Callbacks ------------------------------------------------------------
|
38
|
+
before_validation :set_slug,
|
39
|
+
:set_date
|
40
|
+
after_save :sync_tags,
|
41
|
+
:sync_categories
|
42
|
+
|
43
|
+
# -- Instance Methods -----------------------------------------------------
|
44
|
+
def tag_names(reload = false)
|
45
|
+
@tag_names = nil if reload
|
46
|
+
@tag_names ||= self.tags.tags.collect(&:name).join(', ')
|
47
|
+
end
|
48
|
+
|
49
|
+
protected
|
50
|
+
|
51
|
+
def set_slug
|
52
|
+
self.slug ||= self.title.to_s.slugify
|
53
|
+
end
|
54
|
+
|
55
|
+
def set_date
|
56
|
+
self.year ||= Time.zone.now.year
|
57
|
+
self.month ||= Time.zone.now.month
|
58
|
+
end
|
59
|
+
|
60
|
+
def sync_tags
|
61
|
+
return unless tag_names
|
62
|
+
self.taggings.for_tags.destroy_all
|
63
|
+
self.tag_names.split(',').map{ |t| t.strip }.uniq.each do |tag_name|
|
64
|
+
self.tags << Blog::Tag.find_or_create_by_name(tag_name)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def sync_categories
|
69
|
+
(self.category_ids || {}).each do |category_id, flag|
|
70
|
+
case flag.to_i
|
71
|
+
when 1
|
72
|
+
if category = Blog::Tag.categories.find_by_id(category_id)
|
73
|
+
category.taggings.create(:post => self)
|
74
|
+
end
|
75
|
+
when 0
|
76
|
+
self.taggings.for_categories.where(:tag_id => category_id).destroy_all
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|