summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/models/page.rb65
1 files changed, 53 insertions, 12 deletions
diff --git a/app/models/page.rb b/app/models/page.rb
index f796228..e5a8d9d 100644
--- a/app/models/page.rb
+++ b/app/models/page.rb
@@ -176,18 +176,34 @@ class Page < ApplicationRecord
176 return nil unless page 176 return nil unless page
177 177
178 self.reload 178 self.reload
179 page.translations.reload
179 180
180 # Clone untranslated attributes 181 # Clone untranslated attributes
181 self.tag_list = page.tag_list 182 self.tag_list = page.tag_list
182 self.template_name ||= page.template_name 183 self.template_name ||= page.template_name
183 self.published_at = page.published_at 184 self.published_at = page.published_at
184 185
185 # Getting rid of the auto-generated empty translations 186 # Clone translated attributes -- update each locale in place rather
186 self.translations.delete_all 187 # than delete-and-recreate, so a locale whose content is genuinely
188 # unchanged keeps its real created_at/updated_at instead of looking
189 # freshly touched on every single save (which was silently defeating
190 # Page.find_with_outdated_translations' whole staleness comparison).
191 # search_vector is excluded deliberately: it's DB-trigger-maintained
192 # from title/abstract, not real content, and comparing a precomputed
193 # tsvector risked a false "changed" from representation noise alone.
194 source_locales = page.translations.map(&:locale)
195 self.translations.where.not(:locale => source_locales).destroy_all
187 196
188 # Clone translated attributes 197 page.translations.each do |source_translation|
189 page.translations.each do |translation| 198 attrs = source_translation.attributes.except("id", "page_id", "created_at", "updated_at", "search_vector")
190 self.translations.create!(translation.attributes.except("id", "page_id", "created_at", "updated_at")) 199 mine = self.translations.find_by(:locale => source_translation.locale)
200
201 if mine
202 changed_attrs = attrs.reject { |k, v| mine.public_send(k) == v }
203 mine.update!(changed_attrs) if changed_attrs.any?
204 else
205 self.translations.create!(attrs)
206 end
191 end 207 end
192 208
193 # Clone asset references 209 # Clone asset references
@@ -196,19 +212,28 @@ class Page < ApplicationRecord
196 self.save 212 self.save
197 end 213 end
198 214
199 def diff_against other, view: :inline 215 def diff_against other, view: :inline, locale: nil
216 if locale
217 mine, theirs = translations.find_by(:locale => locale), other.translations.find_by(:locale => locale)
218 my_title, my_abstract, my_body = mine&.title, mine&.abstract, mine&.body
219 their_title, their_abstract, their_body = theirs&.title, theirs&.abstract, theirs&.body
220 else
221 my_title, my_abstract, my_body = title, abstract, body
222 their_title, their_abstract, their_body = other.title, other.abstract, other.body
223 end
224
200 text_diffs = 225 text_diffs =
201 if view == :side_by_side 226 if view == :side_by_side
202 { 227 {
203 title: HtmlWordDiff.side_by_side(other.title.to_s, title.to_s), 228 title: HtmlWordDiff.side_by_side(their_title.to_s, my_title.to_s),
204 abstract: HtmlWordDiff.side_by_side(other.abstract.to_s, abstract.to_s), 229 abstract: HtmlWordDiff.side_by_side(their_abstract.to_s, my_abstract.to_s),
205 body: HtmlWordDiff.side_by_side(other.body.to_s, body.to_s) 230 body: HtmlWordDiff.side_by_side(their_body.to_s, my_body.to_s)
206 } 231 }
207 else 232 else
208 { 233 {
209 title: HtmlWordDiff.inline(other.title.to_s, title.to_s), 234 title: HtmlWordDiff.inline(their_title.to_s, my_title.to_s),
210 abstract: HtmlWordDiff.inline(other.abstract.to_s, abstract.to_s), 235 abstract: HtmlWordDiff.inline(their_abstract.to_s, my_abstract.to_s),
211 body: HtmlWordDiff.inline(other.body.to_s, body.to_s) 236 body: HtmlWordDiff.inline(their_body.to_s, my_body.to_s)
212 } 237 }
213 end 238 end
214 239
@@ -219,6 +244,22 @@ class Page < ApplicationRecord
219 ) 244 )
220 end 245 end
221 246
247 def locale_diff_summary other
248 (translated_locales | other.translated_locales).sort_by(&:to_s).map do |locale|
249 mine = translations.find_by(:locale => locale)
250 theirs = other.translations.find_by(:locale => locale)
251 {
252 :locale => locale,
253 :exists_here => mine.present?,
254 :exists_there => theirs.present?,
255 :changed => mine.present? != theirs.present? ||
256 mine&.title != theirs&.title ||
257 mine&.abstract != theirs&.abstract ||
258 mine&.body != theirs&.body
259 }
260 end
261 end
262
222 def public? 263 def public?
223 published_at.nil? ? true : published_at < Time.now 264 published_at.nil? ? true : published_at < Time.now
224 end 265 end