首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从父类继承类定义

从父类继承类定义
EN

Stack Overflow用户
提问于 2017-11-18 21:26:17
回答 1查看 674关注 0票数 0

我正在我的Rails模型中构建葡萄实体,如下所述:

https://github.com/ruby-grape/grape-entity#entity-organization

目前,我正在根据模型本身的列哈希自动创建默认值。

因此,我有一个静态get_entity方法,它公开了模型的所有列:

代码语言:javascript
复制
class ApplicationRecord < ActiveRecord::Base

  def self.get_entity(target)
    self.columns_hash.each do |name, column|
      target.expose name, documentation: { desc: "Col #{name} of #{self.to_s}" }
    end
  end

end

然后,在声明的实体子类中使用它的示例Book模型(注释还显示了如何覆盖模型的一个列的文档):

代码语言:javascript
复制
class Book < ActiveRecord::Base

  class Entity < Grape::Entity
    Book::get_entity(self)
    # expose :some_column, documentation: {desc: "this is an override"}
  end

end

这种方法的缺点是,我总是需要在我想要实体的每个模型中复制和粘贴类实体声明。

有人能帮助我自动地为ApplicationRecord的所有子级生成类实体吗?然后,如果我需要重写,我将需要在类中有实体声明,否则,如果默认声明足够,可以保持它的原样。

注意:

我不能在ApplicationRecord中直接添加类实体定义,因为实体类应该调用get_entity,而get_entity依赖于图书的column_hash。

解决办法:

最后,多亏了“脑力袋”:

代码语言:javascript
复制
def self.inherited(subclass)
  super
  # definition of Entity
  entity = Class.new(Grape::Entity)
  entity.class_eval do
    subclass.get_entity(entity)
  end
  subclass.const_set "Entity", entity

  # definition of EntityList
  entity_list = Class.new(Grape::Entity)
  entity_list.class_eval do
    expose :items, with: subclass::Entity
    expose :meta, with: V1::Entities::Meta
  end
  subclass.const_set "EntityList", entity_list
end

def self.get_entity(entity)
  model = self
  model.columns_hash.each do |name, column|
    entity.expose name, documentation: { type: "#{V1::Base::get_grape_type(column.type)}", desc: "The column #{name} of the #{model.to_s.underscore.humanize.downcase}" }
  end
end

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-18 21:59:59

我还没有使用葡萄,所以这里可能有一些我不知道的额外魔法,但是这在Ruby/Rails中很容易做到。根据您的问题“自动为ApplicationRecord的所有子级生成类实体”,您可以这样做:

代码语言:javascript
复制
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  class Entity < Grape::Entity
    # whatever shared stuff you want
  end
end

之后,Book将可以访问父Entity

代码语言:javascript
复制
> Book::Entity
=> ApplicationRecord::Entity

如果只想向Book::Entity添加额外的代码,可以在Book中对其进行子类处理,如下所示:

代码语言:javascript
复制
class Book < ApplicationRecord
  class Entity < Entity # subclasses the parent Entity, don't forget this
    # whatever Book-specific stuff you want
  end
end

那么Book::Entity将是它自己的类。

代码语言:javascript
复制
> Book::Entity
=> Book::Entity

要将此与对继承类调用get_entity的需求结合起来,您可以在任何时候使用#inherited方法自动调用get_entity子类:

代码语言:javascript
复制
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  def self.get_entity(target)
    target.columns_hash.each do |name, column|
      target.expose name, documentation: { desc: "Col #{name} of #{self.to_s}" }
    end
  end

  def self.inherited(subclass)
    super
    get_entity(subclass)
  end

  class Entity < Grape::Entity
    # whatever shared stuff you want
  end
end
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47371243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档