如何自动向rails模块中的模型对象添加和序列化虚拟属性?
How to automatically add and serialize virtual attribute to model object in rails module?
如果 Plugin
名称为 SomePluggin
,如何修饰 Plugin
对象以自动向属性添加虚拟 page_links
属性?
示例:
@page.plugins
# As is => [#<Plugin id: 241, url: "some_url", page_id: 118>]
# As I want to be: => [#<Plugin id: 241, url: "some_url", page_links: "1234,main_page,articles", page_id: 118>]
当前代码:
module Cms
class SomePluggin
def initialize(plugin)
@url = plugin.url
#it doesn't work
plugin.page_links = "1234,main_page,articles"
plugin.attributes.merge!("page_links" => "1234,main_page,articles")
#decorate = SimpleDelegator.new plugin
end
def get_content
puts "content"
end
end
module Pluggin
extend ActiveSupport::Concern
included do
after_initialize :pluggin
end
delegate :get_content, to: :pluggin
attr_writer :pluggin
def pluggin
@pluggin ||= "Cms::Pluggin::#{name}".camelize.constantize.new(self) # name=SomePluggin
end
end
end
型号:
class Plugin < ActiveRecord::Base
attr_accessor :page_links
belongs_to :page
include Cms::Pluggin
end
我假设 page_links
是虚拟属性。你的代码结构比较复杂,你基本上可以在class Plugin
中添加page_links
和page_links=
方法初始化,但是如果你想在SomePluggin
中保留这个属性,你可以这样做它是这样的:
module Cms
class SomePluggin
attr_accessor :page_links
def initialize
self.page_links = "1234,main_page,articles"
end
def get_content
puts "content"
end
end
module Pluggin
extend ActiveSupport::Concern
included do
after_initialize :wrap_object
end
def wrap_object
pluggin
end
delegate :get_content, :page_links, :page_links=, to: :pluggin
attr_writer :pluggin
def pluggin
@pluggin ||= SomePluggin.new
end
end
end
这里我在SomePluggin
中添加了:page_links
和:page_links=
方法,在initialize
方法中设置了初始值。
一些控制台输出:
p = Plugin.new
p.page_links # => "1234,main_page,articles"
p.page_links = '123'
p.page_links # => "123"
如果 Plugin
名称为 SomePluggin
,如何修饰 Plugin
对象以自动向属性添加虚拟 page_links
属性?
示例:
@page.plugins
# As is => [#<Plugin id: 241, url: "some_url", page_id: 118>]
# As I want to be: => [#<Plugin id: 241, url: "some_url", page_links: "1234,main_page,articles", page_id: 118>]
当前代码:
module Cms
class SomePluggin
def initialize(plugin)
@url = plugin.url
#it doesn't work
plugin.page_links = "1234,main_page,articles"
plugin.attributes.merge!("page_links" => "1234,main_page,articles")
#decorate = SimpleDelegator.new plugin
end
def get_content
puts "content"
end
end
module Pluggin
extend ActiveSupport::Concern
included do
after_initialize :pluggin
end
delegate :get_content, to: :pluggin
attr_writer :pluggin
def pluggin
@pluggin ||= "Cms::Pluggin::#{name}".camelize.constantize.new(self) # name=SomePluggin
end
end
end
型号:
class Plugin < ActiveRecord::Base
attr_accessor :page_links
belongs_to :page
include Cms::Pluggin
end
我假设 page_links
是虚拟属性。你的代码结构比较复杂,你基本上可以在class Plugin
中添加page_links
和page_links=
方法初始化,但是如果你想在SomePluggin
中保留这个属性,你可以这样做它是这样的:
module Cms
class SomePluggin
attr_accessor :page_links
def initialize
self.page_links = "1234,main_page,articles"
end
def get_content
puts "content"
end
end
module Pluggin
extend ActiveSupport::Concern
included do
after_initialize :wrap_object
end
def wrap_object
pluggin
end
delegate :get_content, :page_links, :page_links=, to: :pluggin
attr_writer :pluggin
def pluggin
@pluggin ||= SomePluggin.new
end
end
end
这里我在SomePluggin
中添加了:page_links
和:page_links=
方法,在initialize
方法中设置了初始值。
一些控制台输出:
p = Plugin.new
p.page_links # => "1234,main_page,articles"
p.page_links = '123'
p.page_links # => "123"