【问题标题】:Method for getting polymorphic relationship table name in Rails. Meta-programmingRails中获取多态关系表名的方法。元编程
【发布时间】:2014-09-30 15:53:05
【问题描述】:

我想测试一个多态孩子是否属于父母。

@event.eventable_id == @current_user.id and @event.eventable_type == current_user.class.name

现在这很难看,不应该出现在这样的视图中。但我想为每个多态对象做这个检查。所以我需要一种元编程的方式来弄清楚多态关系表的命名方案。

phone to phonable
social to sociable
etc.

这个方法看起来很棒。

if @event.belongs_to(current_user) #<NoMethodError: undefined method `belongs_to' for #<Event:

所以我需要一个辅助方法来检查多态关系。如果我能得到任何像这样的多态孩子的名字方案

@event.polymorphic_relationship_table_name

然后我可以将它合并到一个元编程助手中。如果已经为此构建了解决方案,请告诉我。

【问题讨论】:

    标签: ruby-on-rails metaprogramming polymorphism


    【解决方案1】:

    我明白了!这就是获取多态关系名称方案的答案。

    @event.class.reflect_on_all_associations(:belongs_to).first.name
    => :eventable # this is the ouput
    

    而且我可以把任何对象实例放在.class.reflect_on_all_associations(:belongs_to).first.name前面

    在这方面对我帮助最大的文档是 Ryan Stenberg 的 Identifying Foreign Key Dependencies from ActiveRecord::Base Classes

    :-)


    示例用法

    首先是一个辅助方法。

    app/helpers/application_helper.rb

    module ApplicationHelper    
      def child_and_parent?(obj, user)
        obj_id = Integer(eval "obj.#{obj.class.reflect_on_all_associations(:belongs_to).first.name}_id")
        obj_type = String(eval "obj.#{obj.class.reflect_on_all_associations(:belongs_to).first.name}_type")
        (user.id == obj_id) and (user.class.name == obj_type)
      end
    end
    

    然后在视图中使用它来移除不属于当前用户的特征。

    app/views/events/index.html.erb 和 app/views/events/show.html.erb

    <% if child_and_parent? @event, current_user %>
      <li><%= link_to 'Edit', edit_event_path(@event) %></li>
      <li><%= link_to 'Delete', @event, method: :delete, data: { confirm: 'Are you sure?' } %></li>
    <% end %>
    

    【讨论】:

    • 非常酷!感谢您的跟进......这很好在武器库中!
    • 对于任何感兴趣的人,我已经编写了一个 gem,它允许您通过每个对象上可用的 :parent 方法访问父对象。 github.com/danielpclark/PolyBelongsTo gem 'poly_belongs_to'
    【解决方案2】:

    您应该能够从实例本身访问您想要和需要的所有内容:

    @event.eventable.class.table_name
    @event.eventable.class.to_s
    

    等等......当我在一个具有几个多态模型的本地应用程序中测试它时,我能够轻松地从这些方法访问父数据,您可以以更简洁的方式将其集成到您的应用程序中比我写的:)。希望对您有所帮助!

    【讨论】:

    • 这仅处理事件对象用例。对于我拥有的所有不同的多态关系类型,我必须在每个用例中手动输入。 .eventable. 部分需要通过某种方法或帮助程序来解决,这样我就可以为所有多态类型编写一种方法... DRY.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多