Rails 如何给对象新增属性?

xiaoping_rubyist · November 03, 2016 · Last by flemon1986 replied at November 04, 2016 · 4337 hits

我想在 Model 的实例对象中添加 testbed_name 这个属性。 Model

class Topology < ActiveRecord::Base
  attr_accessor :testbed_name
end

class TopologiesController < ApplicationController
  def show
     @topo = Topology.find(2)
     @topo.testbed_name = "VTB100"

     Rails.logger.info "#{@topo.inspect}"  

   respond_to |format|
       format.html
       format.json { render json: @topology }
   end
   end
end

目前的输出 log 中仍然没有 testbed_name 这个属性,我想把 testbed_name 这个属性加入到@topo里面该怎么做?

修改数据库可以,添加属性。还有其他办法么?

属性已经加成功了,只是 inspect 没有输出而已,这个不用担心

#1 楼 @huacnlee 谢谢,还有一个问题。 Model

class Topology < ActiveRecord::Base
  attr_accessor :testbed_name
end

class TopologiesController < ApplicationController
  def show
     @topo = Topology.find(2)
     @topo.testbed_name = "VTB100"


    # Rails.logger.info "#{@topo.inspect}"  

       if params[:format] == "json" then
          @topology.topology_definition_unresolved = JSON.parse(@topology.topology_definition_unresolved)
       end

   respond_to do |format|
       format.html
       format.json { render json: @topology }
   end
   end
end

我想输出json格式的数据。发现并没有testbed_name这个属性。而且@topology.topology_definition_unresolved里面的数据并没有格式化成json数据。但是在3.2版本的rails里面就没问题。看了下rails upgradeguide也并没有讲到这点。

#1 楼 @huacnlee 不好意思再问一下,为什么 topology_definition_resolved 没有解析成 json 格式呢?Rails 4.2.5 http://10.6.1.251:3000/topologies/47452.json

{
testbed_name: "VTB510",
hold_time: 30,
created_at: "2016-10-27T01:51:53.666Z",
created_by: "ayzhang",
location_id: 3,
status: "INUSE",
testbed_id: 230,
topology_definition_resolved: "{"nodes"=>[{"name"=>"RemoteGEN5", "platform"=>"NSA 3500", "physical"=>true, "team"=>"UTM", "attributes"=>"team=UTM,testuse=remote", "interfaces"=>[{"name"=>"X0", "remote_node"=>"PC2", "remote_interface"=>"eth0", "network"=>"172.16.1.0/24", "ip"=>"172.1.1.1"}],}"
}

#1 楼 @huacnlee 不好意思,打扰了,想了好久,搜了好多也没找到答案。而在 Rails 3.2 里面可以输出 json 格式。

{
created_at: "2016-11-02T01:47:45Z",
created_by: "weshen",
hold_time: 30,
location_id: 3,
status: "TERMINATED",
testbed_id: 232,
testbed_name: "VTB512",
topology_definition_resolved: {
nodes: [
{
name: "UTM",
platform: "NSA 5600",
dut: true,
physical: true,
team: "UTM",
attributes: "team=UTM,testuse=dut",
interfaces: [
{
name: "X0",
remote_node: "PC1",
remote_interface: "eth0",
ip: "192.168.168.168",
network: "192.168.168.0/24",
vlan: 272,
physnet: "physnet1",
external_network: "ext_net",
switch_id: 66,
switch_port: "gigabitethernet 0/24",
vlan_type: "untag"
},
{
name: "X1",
network: "12.12.1.0/24",
ip: "",
vlan: 273,
physnet: "physnet1",
external_network: "ext_net",
switch_id: 66,
switch_port: "gigabitethernet 0/25",
vlan_type: "untag"
},
{
name: "X2",
network: "23.0.0.0/24",
ip: "",
vlan: 274,
physnet: "physnet1",
external_network: "ext_net",
switch_id: 66,
switch_port: "gigabitethernet 0/26",
vlan_type: "untag"
},
{
name: "X3",
network: "192.168.101.0/24",
ip: "",
vlan: 275,
physnet: "physnet1",
external_network: "ext_net",
switch_id: 66,
switch_port: "gigabitethernet 0/27",
vlan_type: "untag"
},
]
}
}

@qinfanpeng @Rei 求大神们帮我解答下 二楼三楼的问题,万分感谢。。

没研究过具体文档,不知道为什么一个行,一个不行, 但是你想把那个不行的搞成行,试试把JSON.parse(object)换成object.as_json

#6 楼 @flemon1986 谢谢,还是不行。真的跪了。一天了,愣是没搞出来。。😂

#7 楼 @xiaoping_rubyist

a = Struct.new(:name, :age, :resolved)
res = a.new
res.resolved = { a: 'a', b: 'b'}
res.name = 'name'
res.age = 'age'
res.to_json

执行后 (ruby-2.1.1)

"{\"name\":\"name\",\"age\":\"age\",\"resolved\":{\"a\":\"a\",\"b\":\"b\"}}"

是要这个结果么?

问问topology_definition_unresolved这个方法返回的是一个实例对象吗?

#9 楼 @flemon1986 就是一个 hash , JSON.parse(String) 返回的

#10 楼 @mystery 转换成 hash 是对的。关键问题难道不是 render json: @topology 为什么没有把所有的数据格式化成 json 格式呢。hash 对象也可以转换成 json 格式。

2.3.0 :052 > a = {"a" =>  1, "b" =>  2}
 => {"a"=>1, "b"=>2}
2.3.0 :053 > a.to_json
 => "{\"a\":1,\"b\":2}"

#10 楼 @mystery render json: @topology

render json: @product You don't need to call to_json on the object that you want to render. If you use the :json option, render will automatically call to_json for you.

试试这个 render json: @topology, methods: :topology_definition_unresolved

#13 楼 @flemon1986 这个 methods 貌似只对新添加的虚拟属性起作用,就比如 attr_accessor :testbed_name.我突然有个疑问。就是中间通过 JSON.parse 把@topology的 topology_definition_unresolved 属性重新赋值成 hash 格式。但是@topology并没有改变。他的 topology_definition_unresolved 还是原来的 String 格式。所以输出来的才是字符串而不是 json 格式的文件。

#14 楼 @xiaoping_rubyist 楼上正解,我也不知道他那个topology_definition_unresolved是什么东西,但是@topology的确成功赋值了,不然输出不会有=>

@mystery,试试这个吧

render json: @topology.as_json.merge(topology_definition_unresolved: JSON[@topology.topology_definition_unresolved])

#15 楼 @flemon1986 哈哈,是我在提问,还真可以了。为啥要这样呢?3.2.12 和 4.2.5 处理 json 格式为什么会有这个差别呢?谢谢啊。

#16 楼 @xiaoping_rubyist 这个我无法告诉你,没读文档。。。但是能大概猜到 rails4.2.5 就取消了自动识别 HASH,自动给你 JSON 化。。。RAILS 现在走的路线是由奢入俭,取消额外的黑魔法功能

You need to Sign in before reply, if you don't have an account, please Sign up first.