Ruby Rails :保存 JSON 并在视图中将其解析回布尔值

Ruby Rails : Saving JSON and Parsing it back to Boolean values in View

EDIT: I need go get in my view the boolean true/false from my database, but the problem is, upon calling it from the databse its returning a string. The datatype of my json_permissions is json. As I read and suggested by others boolean true/false is a valid json and on save its being saved as a Hash already (which is true because on debug it'll have the Hash format I'll show below).

如果我在 .to_json 之前调试并查看我的参数表单数据,这就是它的样子:

我是这样解析的(ActiveAdmin):

member_action :update_permissions, method: :put do
   resource.json_permissions = JSON.parse(params.to_json)
   resource.save
   redirect_to admin_group_path(resource)
end

EDIT: I'm saving the resource like this now (explanation from .to_json vs JSON.parse:

member_action :update_permissions, method: :put do
   resource.json_permissions = params.to_json
   resource.save
   redirect_to admin_group_path(resource)
end

在调试时,它已经是一个散列:

binding.pry 参数在 .to_json 之前

.to_json 之后的控制台上,我可以看到这是 stringi-fied(有什么办法可以防止这种情况发生吗?)

[["json_permissions", "{\"utf8\":\"✓\",\"_method\":\"put\",\"authenticity_token\":\"kjRYKDQZAMCZPvw/jQZvh0pyCPJ11Q30zROdh8WVohI=\",\"view_accounts\":\"true\",\"view_admin\":\"true\",\"view_admin_users\":\"true\",\"add_edit_admin_users\":\"true\",\"view_groups\":\"true\",\"add_edit_groups\":\"true\",\"view_jobs\":\"true\",\"view_reports\":\"true\",,\"commit\":\"Update Group Permissions\",\"action\":\"update_permissions\",\"controller\":\"admin/groups\",\"id\":\"3\"}"], ["updated_at", "2018-11-09 05:28:19.859162"]]

然后在我的 show 中查看 Rails:

show do
    resource.json_permissions.each do |key, value|
     if value == "true" || value == "false"
       resource.json_permissions[key] = !!value
     end
    end
    resource.save
    render('admin/groups/show', { group: group})
end

EDIT: I changed my code to the following to make sure I'm re-assigning a boolean true/false on the model before save again.

show do
  resource.json_permissions.each do |key, value|
    if value == "true"
        resource.json_permissions[key] = true
    elsif value == "false"
        resource.json_permissions[key] = false
    end
    resource.save
  end      
  binding.pry
  render('admin/groups/show', { group: group})
end

在 binding.pry 之前保存 - 在 resource.save 之前的循环内,它现在更改为 boolean:

#<Group id: 3, group_name: "Treasury", group_description: "Treasury Department", active: true, created_at: "2018-10-23 06:08:48", updated_at: "2018-11-09 05:28:19", created_by: "maria.mendoza@sci.ph", updated_by: "maria.mendoza@sci.ph", json_permissions: {"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"kjRYKDQZAMCZPvw/jQZvh0pyCPJ11Q30zROdh8WVohI=", "view_accounts"=>true, "view_bank_accounts"=>true, "add_edit_bank_accounts"=>true, "view_recipient_accounts"=>true,.... >

在 binding.pry 上再次保存后检查 resource/group 的内容,现在具有正确的 boolean 值。

遗憾的是,在为视图再次保存之前使用 double bang 运算符,

Still returns a Hash string value on true/false

检查数据库后-确实它仍然保存为字符串,所以现在不奇怪为什么保存后在我的调试中没有得到 boolean true/false

{
"add_edit_admin_users": "false",
"view_user_accounts": "false",
"view_reports": "false",
    ...
    ...
    ...
}

这是否与将 save 转换回 string 有关?

我的表单在 POST

上看起来像这样
<%= simple_form_for([:admin, resource], url: update_permissions_admin_group_path(resource), method: :put) do |f| %>
<div class="panel">
    <div class="panel_contents">
        <div class="attributes_table">
            <ul class="tree" id="tree">
                <li>
                    <%= hidden_field_tag 'view_accounts', false %>
                    <%= check_box_tag 'view_accounts', checked = true %> View Accounts 
                    <ul>
                        <li>
                        <%= hidden_field_tag 'view_bank_accounts', false %>
                        <%= check_box_tag 'view_bank_accounts', checked = true %> View Bank Accounts </li>
                        <li>

EDIT: Explicitly re-assigning a boolean does the TRICK :)

!!string

将永远return true:

!!"false" # true
!!"true"  # true

您可以将作业写成

resource.json_permissions[key][value] = ( value == "true" )

括号是可选的,但它们增加了可读性。

show do
   resource.json_permissions.each do |key, value|
       if value == "true"
           resource.json_permissions[key] = true
       elsif value == "false"
           resource.json_permissions[key] = false
       end
       resource.save
     end      
     binding.pry
     render('admin/groups/show', { group: group})
end

出于某种原因,像这样将其显式转换为布尔值就可以解决问题。即使在检查我的数据库时 true/false 仍然保存为字符串。