merbiful-release 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -1,12 +1,11 @@
1
1
  require 'rubygems'
2
2
  require 'rake/gempackagetask'
3
3
  require 'spec'
4
- require 'spec/rake/spectask'
5
4
  require 'pathname'
6
5
 
7
6
  PLUGIN = "merbiful-release"
8
7
  NAME = "merbiful-release"
9
- GEM_VERSION = "0.0.2"
8
+ GEM_VERSION = "0.0.3"
10
9
  AUTHOR = "Martin Kihlgren"
11
10
  EMAIL = "martin@wemind.se"
12
11
  HOMEPAGE = ""
@@ -38,7 +37,7 @@ task :install => [:package] do
38
37
  end
39
38
 
40
39
  desc "Run specifications"
41
- Spec::Rake::SpecTask.new('spec') do |t|
42
- t.spec_opts = ["--format", "specdoc", "--colour"]
43
- t.spec_files = Pathname.glob(Pathname.new(__FILE__).parent.join("spec").join("**").join("*_spec.rb"))
40
+ task :spec do
41
+ Dir.chdir(File.join(File.dirname(__FILE__), "spec"))
42
+ system("rake spec")
44
43
  end
@@ -122,17 +122,13 @@ module Merbiful
122
122
 
123
123
  def destroy_page
124
124
  page = Page.get(params[:page_id])
125
- page.versions.each do |version|
126
- version.css_nesses.destroy!
127
- version.js_nesses.destroy!
128
- version.destroy
129
- end
130
125
  page.destroy
131
126
  redirect url(:merbiful_admin, :action => "pages")
132
127
  end
133
128
 
134
129
  def upload_image
135
130
  path = Pathname.new(File.join(Merb.root, "public", "images", File.basename(params[:image][:filename])))
131
+ raise "H4xx0r" unless path.to_s.index(Pathname.new(Merb.root).expand_path.to_s) == 0
136
132
  Pathname.new(params[:image][:tempfile].path).rename(path)
137
133
  redirect url(:merbiful_admin, :action => "images")
138
134
  end
@@ -146,27 +142,18 @@ module Merbiful
146
142
 
147
143
  def destroy_layout
148
144
  layout = Layout.get(params[:layout_id])
149
- layout.page_versions.each do |page_version|
150
- page_version.layout = nil
151
- page_version.save
152
- end
153
- layout.layout_versions.destroy!
154
145
  layout.destroy
155
146
  redirect url(:merbiful_admin, :action => "layouts")
156
147
  end
157
148
 
158
149
  def destroy_css
159
150
  css = Css.get(params[:css_id])
160
- css.css_nesses.destroy!
161
- css.css_versions.destroy!
162
151
  css.destroy
163
152
  redirect url(:merbiful_admin, :action => "css")
164
153
  end
165
154
 
166
155
  def destroy_js
167
156
  js = Js.get(params[:js_id])
168
- js.js_nesses.destroy!
169
- js.js_versions.destroy!
170
157
  js.destroy
171
158
  redirect url(:merbiful_admin, :action => "js")
172
159
  end
@@ -181,19 +168,19 @@ module Merbiful
181
168
  def create_css
182
169
  new_css = Css.create(:name => next_name(Css))
183
170
  new_css_version = Css::Version.create(:css => new_css)
184
- redirect url(:merbiful_admin, :action => 'css')
171
+ redirect url(:merbiful_admin, :action => 'css', :css_id => new_css.id)
185
172
  end
186
173
 
187
174
  def create_js
188
175
  new_js = Js.create(:name => next_name(Js))
189
176
  new_js_version = Js::Version.create(:js => new_js)
190
- redirect url(:merbiful_admin, :action => 'js')
177
+ redirect url(:merbiful_admin, :action => 'js', :js_id => new_js.id)
191
178
  end
192
179
 
193
180
  def create_layout
194
181
  new_layout = Layout.create(:name => next_name(Layout))
195
182
  new_layout_version = Layout::Version.create(:layout => new_layout)
196
- redirect url(:merbiful_admin, :action => 'layouts')
183
+ redirect url(:merbiful_admin, :action => 'layouts', :layout_id => new_layout.id)
197
184
  end
198
185
 
199
186
  def move_page_up
@@ -1,10 +1,291 @@
1
1
 
2
2
  module Merbiful
3
3
 
4
- class Controller < Merb::Controller
4
+ class Admin < Merb::Controller
5
+
6
+ include RelativeTimeHelpers
7
+
8
+ def index
9
+ render_template_with_layout("index.html.haml")
10
+ end
11
+
12
+ def layouts
13
+ @form_layout = Layout.get(params[:layout_id])
14
+ if request.post?
15
+ @form_layout.update_attributes(params[:layout])
16
+ if @form_layout.valid?
17
+ @form_layout.save
18
+ @form_version = Layout::Version.new(params[:version].merge(:layout => @form_layout))
19
+ if @form_version.valid?
20
+ @form_version.save
21
+ redirect url(:merbiful_admin, :action => "layouts", :layout_id => @form_layout.id)
22
+ end
23
+ end
24
+ else
25
+ if @form_layout
26
+ @form_version = Layout::Version.get(params[:version_id])
27
+ @form_version = @form_layout.latest unless @form_version
28
+ end
29
+ end
30
+ render_template_with_layout("layouts.html.haml")
31
+ end
32
+
33
+ def js
34
+ @form_js = Js.get(params[:js_id])
35
+ if request.post?
36
+ params[:js][:cached] = !!params[:js][:cached]
37
+ @form_js.update_attributes(params[:js])
38
+ if @form_js.valid?
39
+ @form_js.save
40
+ @form_version = Js::Version.new(params[:version].merge(:js => @form_js))
41
+ if @form_version.valid?
42
+ @form_version.save
43
+ redirect url(:merbiful_admin, :action => "js", :js_id => @form_js.id)
44
+ end
45
+ end
46
+ else
47
+ if @form_js
48
+ @form_version = Js::Version.get(params[:version_id])
49
+ @form_version = @form_js.latest unless @form_version
50
+ end
51
+ end
52
+ render_template_with_layout("js.html.haml")
53
+ end
54
+
55
+ def images
56
+ if request.post?
57
+ end
58
+ render_template_with_layout("images.html.haml")
59
+ end
60
+
61
+ def css
62
+ @form_css = Css.get(params[:css_id])
63
+ if request.post?
64
+ params[:css][:cached] = !!params[:css][:cached]
65
+ @form_css.update_attributes(params[:css])
66
+ if @form_css.valid?
67
+ @form_css.save
68
+ @form_version = Css::Version.new(params[:version].merge(:css => @form_css))
69
+ if @form_version.valid?
70
+ @form_version.save
71
+ redirect url(:merbiful_admin, :action => "css", :css_id => @form_css.id)
72
+ end
73
+ end
74
+ else
75
+ if @form_css
76
+ @form_version = Css::Version.get(params[:version_id])
77
+ @form_version = @form_css.latest unless @form_version
78
+ end
79
+ end
80
+ render_template_with_layout("css.html.haml")
81
+ end
82
+
83
+ def pages
84
+ if Page.count == 0
85
+ new_root = Page.create(:path => "/")
86
+ new_root_version = Page::Version.create(:page => new_root, :body => "Here be Dagon")
87
+ end
88
+ @form_page = Page.get(params[:page_id])
89
+ if request.post?
90
+ params[:page][:cached] = !!params[:page][:cached]
91
+ @form_page.update_attributes(params[:page])
92
+ if @form_page.valid?
93
+ @form_page.save
94
+ version_csses = params[:version].delete(:css)
95
+ version_jses = params[:version].delete(:js)
96
+ @form_version = Page::Version.new(params[:version].merge(:page => @form_page))
97
+ version_csses.each do |css|
98
+ @form_version.add_css(Css.get(css))
99
+ end if version_csses
100
+ version_jses.each do |js|
101
+ @form_version.add_js(Js.get(js))
102
+ end if version_jses
103
+ if @form_version.valid?
104
+ @form_version.save
105
+ redirect url(:merbiful_admin, :action => "pages", :page_id => @form_page.id)
106
+ end
107
+ end
108
+ else
109
+ if @form_page
110
+ @form_version = Page::Version.get(params[:version_id])
111
+ @form_version = @form_page.latest unless @form_version
112
+ end
113
+ end
114
+ render_with_layout(Page.all(:parent_id => nil).collect do |page|
115
+ "<ul class='root'>\n#{render_page(page)}\n</ul>"
116
+ end.join("\n"))
117
+ end
118
+
119
+ def render_css
120
+ read_template("admin.css")
121
+ end
122
+
123
+ def destroy_page
124
+ page = Page.get(params[:page_id])
125
+ page.versions.each do |version|
126
+ version.css_nesses.destroy!
127
+ version.js_nesses.destroy!
128
+ version.destroy
129
+ end
130
+ page.destroy
131
+ redirect url(:merbiful_admin, :action => "pages")
132
+ end
133
+
134
+ def upload_image
135
+ path = Pathname.new(File.join(Merb.root, "public", "images", File.basename(params[:image][:filename])))
136
+ Pathname.new(params[:image][:tempfile].path).rename(path)
137
+ redirect url(:merbiful_admin, :action => "images")
138
+ end
139
+
140
+ def delete_image
141
+ path = Pathname.new(File.join(Merb.root, "public", params[:path])).expand_path
142
+ raise "H4xx0r" unless path.to_s.index(Pathname.new(Merb.root).expand_path.to_s) == 0
143
+ path.unlink
144
+ redirect url(:merbiful_admin, :action => "images")
145
+ end
146
+
147
+ def destroy_layout
148
+ layout = Layout.get(params[:layout_id])
149
+ layout.page_versions.each do |page_version|
150
+ page_version.layout = nil
151
+ page_version.save
152
+ end
153
+ layout.layout_versions.destroy!
154
+ layout.destroy
155
+ redirect url(:merbiful_admin, :action => "layouts")
156
+ end
157
+
158
+ def destroy_css
159
+ css = Css.get(params[:css_id])
160
+ css.css_nesses.destroy!
161
+ css.css_versions.destroy!
162
+ css.destroy
163
+ redirect url(:merbiful_admin, :action => "css")
164
+ end
165
+
166
+ def destroy_js
167
+ js = Js.get(params[:js_id])
168
+ js.js_nesses.destroy!
169
+ js.js_versions.destroy!
170
+ js.destroy
171
+ redirect url(:merbiful_admin, :action => "js")
172
+ end
173
+
174
+ def create_page
175
+ parent = Page.get(params[:parent_id])
176
+ new_page = Page.create(:parent => parent, :path => next_path(parent.path))
177
+ new_page_version = Page::Version.create(:page => new_page)
178
+ redirect url(:merbiful_admin, :action => "pages", :page_id => new_page.id)
179
+ end
180
+
181
+ def create_css
182
+ new_css = Css.create(:name => next_name(Css))
183
+ new_css_version = Css::Version.create(:css => new_css)
184
+ redirect url(:merbiful_admin, :action => 'css')
185
+ end
186
+
187
+ def create_js
188
+ new_js = Js.create(:name => next_name(Js))
189
+ new_js_version = Js::Version.create(:js => new_js)
190
+ redirect url(:merbiful_admin, :action => 'js')
191
+ end
192
+
193
+ def create_layout
194
+ new_layout = Layout.create(:name => next_name(Layout))
195
+ new_layout_version = Layout::Version.create(:layout => new_layout)
196
+ redirect url(:merbiful_admin, :action => 'layouts')
197
+ end
198
+
199
+ def move_page_up
200
+ page = Page.get(params[:page_id])
201
+ page.position -= 1
202
+ page.save
203
+ redirect url(:merbiful_admin, :action => "pages")
204
+ end
205
+
206
+ def move_page_down
207
+ page = Page.get(params[:page_id])
208
+ page.position += 1
209
+ page.save
210
+ redirect url(:merbiful_admin, :action => "pages")
211
+ end
212
+
213
+ private
214
+
215
+ def text_area_rows
216
+ 20
217
+ end
218
+
219
+ def next_path(parent_path)
220
+ index = 0
221
+ while Page.first(:path => File.join(parent_path, index.to_s))
222
+ index += 1
223
+ end
224
+ return File.join(parent_path, index.to_s)
225
+ end
226
+
227
+ def next_name(klass)
228
+ index = 0
229
+ while klass.first(:name => index.to_s)
230
+ index += 1
231
+ end
232
+ return index.to_s
233
+ end
234
+
235
+ def errors(obj, meth)
236
+ return ""
237
+ if obj.errors.on(meth)
238
+ obj.errors.on(meth).join(", ")
239
+ else
240
+ ""
241
+ end
242
+ end
243
+
244
+ def render_children(page, ind = "")
245
+ rval = []
246
+ rval << "<ul class='children'>"
247
+ page.children(:order => [:position, :id]).each do |child|
248
+ rval << render_page(child, ind + " ")
249
+ end
250
+ rval << "</ul>"
251
+ return rval.collect do |line| ind + line end.join("\n")
252
+ end
5
253
 
6
- def display(what)
7
- render what.inspect
254
+ def render_page(page, ind = "")
255
+ rval = []
256
+ rval << "<li class='page'>"
257
+ rval << "<ul class='page_info info'>"
258
+ rval << "<a href='#{url(:merbiful_admin, :action => 'pages', :page_id => page.id)}'>"
259
+ rval << "<li class='page_path'>#{page.path}</li>"
260
+ rval << "<li class='page_title'>#{page.title || "untitled"}</li>"
261
+ rval << "<li class='page_version'>ver##{page.latest.id} (#{time_ago_in_words(page.latest.created_at)} ago)</li>"
262
+ rval << "</a>"
263
+ rval << "<li class='up'><a href='#{url(:merbiful_admin, :action => 'move_page_up', :page_id => page.id)}'>&uarr;</a></li>"
264
+ rval << "<li class='down'><a href='#{url(:merbiful_admin, :action => 'move_page_down', :page_id => page.id)}'>&darr;</a></li>"
265
+ rval << "<li class='remove'><a href='#{url(:merbiful_admin, :action => 'destroy_page', :page_id => page.id)}'>-</a></li>" unless page.parent_id.nil?
266
+ rval << "<li class='append'><a href='#{url(:merbiful_admin, :action => 'create_page', :parent_id => page.id)}'>+</a></li>"
267
+ rval << "</ul>"
268
+ rval << render_template_without_layout("page_form.html.haml") if params[:page_id].to_s == page.id.to_s
269
+ rval << render_children(page, ind) unless page.children.empty?
270
+ rval << "</li>"
271
+ return rval.collect do |line| ind + line end.join("\n")
272
+ end
273
+
274
+ def read_template(template)
275
+ Pathname.new(__FILE__).parent.parent.parent.join("templates").join(template).read
276
+ end
277
+
278
+ def render_with_layout(text)
279
+ throw_content :for_layout, text
280
+ ::Haml::Engine.new(read_template("admin_layout.html.haml")).render(self)
281
+ end
282
+
283
+ def render_template_with_layout(template)
284
+ render_with_layout(::Haml::Engine.new(read_template(template)).render(self))
285
+ end
286
+
287
+ def render_template_without_layout(template)
288
+ ::Haml::Engine.new(read_template(template)).render(self)
8
289
  end
9
290
 
10
291
  end
@@ -2,14 +2,35 @@
2
2
  module Merbiful
3
3
 
4
4
  module Body
5
- def to_html(controller)
6
- if self.filter.nil?
7
- self.body
8
- else
9
- filter_class = Merbiful.const_get(self.filter.to_sym)
10
- filter_class.new.render(self.body, controller)
5
+
6
+ def render(controller, caches = {})
7
+ rval = if self.filter.blank?
8
+ self.body
9
+ else
10
+ filter_class = Merbiful.const_get(self.filter.to_sym)
11
+ filter_class.new.render(self.body, controller)
12
+ end
13
+ unless Merb.environment == "development"
14
+ caches.each do |destination, to_cache|
15
+ if to_cache
16
+ path = Pathname.new(File.join(Merb.root, "public", destination))
17
+ Merb.logger.info("Flushing to #{path.inspect}")
18
+ path.parent.mkpath
19
+ path.open("w") do |out|
20
+ out.write(rval)
21
+ end
22
+ end
23
+ end
11
24
  end
25
+ return rval
26
+ end
27
+
28
+ def clear_cache(target)
29
+ return if target == "/"
30
+ path = Pathname.new(File.join(Merb.root, "public", target))
31
+ path.unlink if path.exist?
12
32
  end
33
+
13
34
  end
14
35
 
15
36
  end
@@ -17,9 +17,14 @@ module Merbiful
17
17
  property :updated_at, DateTime
18
18
 
19
19
  has n, :css_nesses, :class_name => "Merbiful::Css::Ness"
20
- has n, :page_versions, :through => :css_nesses, :class_name => "Merbiful::Page::Version"
20
+ has n, :page_versions, :through => :css_nesses, :class_name => "Merbiful::Page::Version", :child_key => [:css_id]
21
21
  has n, :css_versions, :class_name => "Merbiful::Css::Version"
22
22
 
23
+ before :destroy do
24
+ css_nesses.destroy!
25
+ css_versions.destroy!
26
+ end
27
+
23
28
  def latest
24
29
  css_versions.first(:css_id => self.id, :order => [:id.desc])
25
30
  end
@@ -35,9 +40,11 @@ module Merbiful
35
40
  include DataMapper::Validate
36
41
 
37
42
  property :id, Serial
43
+ property :page_version_id, Integer
44
+ property :css_id, Integer
38
45
 
39
- belongs_to :css, :class_name => "Merbiful::Css"
40
- belongs_to :page_version, :class_name => "Merbiful::Page::Version"
46
+ belongs_to :css, :class_name => "Merbiful::Css", :child_key => [:css_id]
47
+ belongs_to :page_version, :class_name => "Merbiful::Page::Version", :child_key => [:page_version_id]
41
48
  end
42
49
 
43
50
  class Version
@@ -21,10 +21,14 @@ module Merbiful
21
21
  has n, :css_versions, :class_name => "Merbiful::Css::Version"
22
22
 
23
23
  def latest
24
- css_versions.first(:order => [:id.desc])
24
+ css_versions.first(:css_id => self.id, :order => [:id.desc])
25
25
  end
26
26
 
27
- def_delegators :latest, :render
27
+ def_delegators :latest, :render, :body, :filter
28
+
29
+ def path
30
+ "/stylesheets/#{latest.id}"
31
+ end
28
32
 
29
33
  class Ness
30
34
  include DataMapper::Resource
@@ -54,6 +58,10 @@ module Merbiful
54
58
 
55
59
  belongs_to :css, :class_name => "Merbiful::Css"
56
60
 
61
+ before :save do
62
+ clear_cache(css.path) if css.latest
63
+ end
64
+
57
65
  end
58
66
 
59
67
  end
@@ -1,11 +1,13 @@
1
1
  module Merbiful
2
2
 
3
- class Eruby
3
+ class Erubis
4
4
 
5
5
  def render(text, scope)
6
- ERB.new(text).result(scope)
6
+ ::Erubis::Eruby.new(text).result(scope.instance_eval do binding end)
7
7
  end
8
8
 
9
9
  end
10
10
 
11
+ FILTERS << Erubis
12
+
11
13
  end
@@ -0,0 +1,14 @@
1
+
2
+ module Merbiful
3
+
4
+ FILTERS = []
5
+
6
+ def self.filters
7
+ FILTERS.inject([[nil, "Verbatim"]]) do |sum, filter|
8
+ filter_name = filter.name.gsub(/^Merbiful::/, "")
9
+ sum + [[filter_name, filter_name]]
10
+ end
11
+ end
12
+
13
+ end
14
+
@@ -3,9 +3,21 @@ module Merbiful
3
3
 
4
4
  class Haml
5
5
 
6
- def render(text)
6
+ def render(text, scope)
7
+ ::Haml::Engine.new(text).render(scope)
7
8
  end
8
9
 
9
10
  end
10
11
 
12
+ class Sass
13
+
14
+ def render(text, scope)
15
+ ::Sass::Engine.new(text).render
16
+ end
17
+
18
+ end
19
+
20
+ FILTERS << Haml
21
+ FILTERS << Sass
22
+
11
23
  end
@@ -0,0 +1,14 @@
1
+
2
+ module Merbiful
3
+
4
+ class ImageHandler
5
+
6
+ IMAGE_REGEXP = /\.(gif|jpg|jpeg|png|bmp)$/
7
+
8
+ def images
9
+
10
+ end
11
+
12
+ end
13
+
14
+ end
@@ -16,9 +16,14 @@ module Merbiful
16
16
  property :updated_at, DateTime
17
17
 
18
18
  has n, :js_nesses, :class_name => "Merbiful::Js::Ness"
19
- has n, :page_versions, :through => :js_nesses, :class_name => "Merbiful::Page::Version"
19
+ has n, :page_versions, :through => :js_nesses, :class_name => "Merbiful::Page::Version", :child_key => [:js_id]
20
20
  has n, :js_versions, :class_name => "Merbiful::Js::Version"
21
21
 
22
+ before :destroy do
23
+ js_nesses.destroy!
24
+ js_versions.destroy!
25
+ end
26
+
22
27
  def latest
23
28
  js_versions.first(:js_id => self.id, :order => [:id.desc])
24
29
  end
@@ -34,9 +39,11 @@ module Merbiful
34
39
  include DataMapper::Validate
35
40
 
36
41
  property :id, Serial
42
+ property :page_version_id, Integer
43
+ property :js_id, Integer
37
44
 
38
- belongs_to :js, :class_name => "Merbiful::Js"
39
- belongs_to :page_version, :class_name => "Merbiful::Page::Version"
45
+ belongs_to :js, :class_name => "Merbiful::Js", :child_key => [:js_id]
46
+ belongs_to :page_version, :class_name => "Merbiful::Page::Version", :child_key => [:page_version_id]
40
47
  end
41
48
 
42
49
  class Version
@@ -1,7 +1,7 @@
1
1
 
2
2
  module Merbiful
3
3
 
4
- class Css
4
+ class Js
5
5
 
6
6
  include DataMapper::Resource
7
7
  include DataMapper::Validate
@@ -10,21 +10,24 @@ module Merbiful
10
10
  property :id, Serial
11
11
 
12
12
  property :name, DataMapper::Types::Text, :nullable => false
13
- property :media, DataMapper::Types::Text
14
13
  property :cached, Boolean, :default => true, :nullable => false
15
14
 
16
15
  property :created_at, DateTime
17
16
  property :updated_at, DateTime
18
17
 
19
- has n, :css_nesses, :class_name => "Merbiful::Css::Ness"
20
- has n, :page_versions, :through => :css_nesses, :class_name => "Merbiful::Page::Version"
21
- has n, :css_versions, :class_name => "Merbiful::Css::Version"
18
+ has n, :js_nesses, :class_name => "Merbiful::Js::Ness"
19
+ has n, :page_versions, :through => :js_nesses, :class_name => "Merbiful::Page::Version"
20
+ has n, :js_versions, :class_name => "Merbiful::Js::Version"
22
21
 
23
22
  def latest
24
- css_versions.first(:order => [:id.desc])
23
+ js_versions.first(:js_id => self.id, :order => [:id.desc])
25
24
  end
26
25
 
27
- def_delegators :latest, :render
26
+ def_delegators :latest, :render, :body, :filter
27
+
28
+ def path
29
+ "/javascripts/#{latest.id}"
30
+ end
28
31
 
29
32
  class Ness
30
33
  include DataMapper::Resource
@@ -32,7 +35,7 @@ module Merbiful
32
35
 
33
36
  property :id, Serial
34
37
 
35
- belongs_to :css, :class_name => "Merbiful::Css"
38
+ belongs_to :js, :class_name => "Merbiful::Js"
36
39
  belongs_to :page_version, :class_name => "Merbiful::Page::Version"
37
40
  end
38
41
 
@@ -44,7 +47,7 @@ module Merbiful
44
47
 
45
48
  property :id, Serial
46
49
 
47
- property :css_id, Integer, :index => true, :nullable => false
50
+ property :js_id, Integer, :index => true, :nullable => false
48
51
 
49
52
  property :body, DataMapper::Types::Text
50
53
  property :filter, DataMapper::Types::Text
@@ -52,8 +55,12 @@ module Merbiful
52
55
  property :created_at, DateTime
53
56
  property :updated_at, DateTime
54
57
 
55
- belongs_to :css, :class_name => "Merbiful::Css"
58
+ belongs_to :js, :class_name => "Merbiful::Js"
56
59
 
60
+ before :save do
61
+ clear_cache(js.path) if js.latest
62
+ end
63
+
57
64
  end
58
65
 
59
66
  end
@@ -17,6 +17,14 @@ module Merbiful
17
17
  has n, :layout_versions, :class_name => "Merbiful::Layout::Version"
18
18
  has n, :page_versions, :class_name => "Merbiful::Page::Version"
19
19
 
20
+ before :destroy do
21
+ page_versions.each do |page_version|
22
+ page_version.layout = nil
23
+ page_version.save
24
+ end
25
+ layout_versions.destroy!
26
+ end
27
+
20
28
  def latest
21
29
  layout_versions.first(:layout_id => self.id, :order => [:id.desc])
22
30
  end