Rails Active Record .to_yaml 文本内容的不同输出

Rails Active Record .to_yaml different output for text content

出于备份原因,我们确实在 ActiveRecord 上使用 .to_yaml 将记录的一些值转储到 .yml 文件中。

这些文件存储在存储库中,因为这些备份数据是设置新系统的默认设置的一部分。

示例:

---
guid: dbYSoCvkzq9z5ZFyRxy0lE
name: bookmarklisting
template: |-
  <div class="template">
    <tpl for=".">
      <div class="x-like-menu-item pointer selection {[xindex%2==0 ? "even" : "odd"]}">
        {[Ext.String.htmlEncode(values.topic||values.title||t("infobase.missing_topic"))]}
      </div>
    </tpl>
  </div>
config: "{ foo:true }"
deactivated: false
created_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: 2012-03-01 13:31:47.296000000 Z
  zone: &1 !ruby/object:ActiveSupport::TimeZone
    name: Europe/Berlin
  time: 2012-03-01 14:31:47.296000000 Z
updated_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: 2021-05-20 16:32:01.093000000 Z
  zone: *1
  time: 2021-05-20 18:32:01.093000000 Z
actors: "-4"
group_name: ''

如您所见,template 包含长 html 模板数据。到目前为止,一切都很好。这工作得很好而且很完美,如果有什么变化很容易在拉取请求中有所不同。

但出于某种原因,有时文本内容会被转义。

示例:

---
guid: aPsOeyYUbumlfZI2yLs2ti
name: infobase
template: "<tpl for=\".\">\n  <a name=\"infobase-{id}\"></a>\n\n  <div class=\"papersheet\"
  style=\"padding:0\">\n    <tpl if=\"folder.folder_type\">\n      <tpl if=\"folder.folder_type.tools.length
  &gt; 0\"><div class=\"buttoncontainer border-bottom\"></div></tpl>\n    </tpl>\n
  \   \n    {[this.infobase.messages(values)]}\n\n    <div class=\"infobase\" style=\"padding:
  5mm 15mm\">\n\n      <div class=\"header greytext border-bottom\">\n        <div
  data-qtip=\"{folder.path}/{folder.name}\">{folder.name:htmlEncode}</div>\n        <div>\n
  \         <tpl if=\"owner.mail\"><a href=\"mailto:{owner.mail}?subject={[escape(values.topic)]}\">{owner.name:htmlEncode}</a></tpl>\n
  \         <tpl if=\"!owner.mail\">{owner.name}</tpl>\n        </div>\n        <div>{[Ext.util.Format.date(values.changed_at,
  InformerContext.format.dateshort)]}</div>\n      </div>\n\n      <div class=\"largetext
  boldtext\" style=\"line-height: 22px;margin:10px 0;\">{topic}</div>\n\n      <tpl
  if=\"attachment.file||attachment.source\">\n        <div class=\"linkcontainer border-bottom\">\n
  \         <tpl if=\"attachment.file\">{attachment.file:this.attachment.link}<br
  /></tpl>\n          <tpl if=\"attachment.source\">{attachment.source:this.attachment.link}</tpl>\n
  \       </div>\n      </tpl>\n\n      <div class=\"content\"><div>{description:nl2br}</div></div>\n\n
  \     <tpl if=\"locked\"><div class=\"lockedcontent mediumtext\">{[t(\"infobase.messages.record_locked\")]}</div></tpl>\n
  \     <tpl if=\"content.length &gt; 0 && locked == false\">\n        <div class=\"content
  clear\">{content}</div>\n        <tpl if=\"attachment.file.media.type == 'video'\"><center>{attachment.file:this.attachment.html5video}</center></tpl>\n
  \       <tpl if=\"attachment.file.media.type == 'flv'\"><center>{attachment.file:this.attachment.flashvideo}</center></tpl>\n
  \     </tpl>\n\n      <tpl if=\"members.length &gt; 0 || member_of.length &gt; 0\">\n
  \       <div class=\"membercontainer border-top\">\n          <tpl if=\"members.length
  &gt; 0 \">\n            <div class=\"memberscontainer\">\n              <span class=\"boldtext\">{[t(\"infobase.effective_documents\")]}</span>\n
  \             <ul>\n              <tpl for=\"members\">\n                <li>\n
  \                 <a href=\"{url.reader}\" target=\"_reader\" data-qtip=\"{[t(\"infobase.folder\")]}:
  {folder.name}\">{topic:htmlEncode}</a>\n                  <tpl if=\"attachment.file\">{attachment.file:this.attachment.iconlink}</tpl>\n
  \               </li>\n              </tpl>\n              </ul>\n            </div>\n
  \         </tpl>\n          <tpl if=\"member_of.length &gt; 0 \">\n            <div
  class=\"memberofcontainer\">\n              <span class=\"boldtext\">{[t(\"infobase.effective_document_of\")]}</span>\n
  \             <ul>\n              <tpl for=\"member_of\">\n                <li>\n
  \                 <a href=\"{url.reader}\" target=\"_reader\" data-qtip=\"{[t(\"infobase.folder\")]}:
  {folder.name}\">{topic:htmlEncode}</a>\n                  <tpl if=\"attachment.file\">{attachment.file:this.attachment.iconlink}</tpl>\n
  \               </li>\n              </tpl>\n              </ul>\n            </div>\n
  \         </tpl>\n          <br style=\"clear:both\"/>\n        </div>\n      </tpl>\n\n
  \     <!--// Alle Zusatzfelder ausgeben //-->\n      <table class=\"profile-table\"
  cellpadding=0 cellspacing=0>\n      <tpl for=\"profiles.keys\">\n        <tr>\n
  \         <th>\n            {[ this.infobase.label(parent[0].profiles[values]) ]}:\n
  \         </th>\n          <td>\n            {[ this.infobase.value(parent[0].profiles[values])
  ]}\n          </td>\n        </tr>\n      </tpl>\n      </table>\n\n    </div>\n
  \ </div>\n</tpl>"
config: "{}"
deactivated: false
created_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: 2011-10-11 10:26:08.906000000 Z
  zone: &1 !ruby/object:ActiveSupport::TimeZone
    name: Europe/Berlin
  time: 2011-10-11 12:26:08.906000000 Z
updated_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: 2021-04-30 09:12:12.726000000 Z
  zone: *1
  time: 2021-04-30 11:12:12.726000000 Z
actors: "-4"
group_name: infobase

到目前为止我看不出与then length或任何特殊字符有什么关系,事实上我没有找出原因是什么。 我确实想像第一个示例一样始终存储模板数据。

那么 .to_yaml 如何以及何时决定是否转义数据,我该如何防止这种行为?

问题在于仅包含空格的行。

这些将根据您的需要设置格式:

puts({ text: "Text A\nText B" }.to_yaml)
---
:text: |-
  Text A
  Text B

puts({ text: "Text A\n\nText B" }.to_yaml)
---
:text: |-
  Text A

  Text B

但这不会:

puts({ text: "Text A\n \nText B" }.to_yaml)
---
:text: "Text A\n \nText B"

此行为可能不会最终生成格式不正确的 YAML。您可能希望在保存数据或序列化之前去除空行。