【问题标题】:Ruby/Rails - Is an "events" method on my user model such a bad idea?Ruby/Rails - 我的用户模型上的“事件”方法是个坏主意吗?
【发布时间】:2015-02-24 06:29:00
【问题描述】:

我正在开发一个应用程序,其中用户参与一个或多个事件,因此可以根据他们在这些事件中扮演的角色说“拥有”事件。我正在使用 Rolify 将用户与事件相关联。 Rolify 根据用户在该事件中所占据的角色形成用户与该事件之间的关联。 Rolify 更关心返回有关用户角色的数据,但不关心用户在其中拥有角色的事件,因此不会返回有关事件的数据(除了其 ID)。

所以,我可以这样写一个方法:

@user.roles

并获取与用户关联的所有角色。

其中一个角色如下所示:

 => #<Role id: 1, name: "admin", resource_id: 1, resource_type: "Event", created_at: "2014-12-19 04:00:33", updated_at: "2014-12-19 04:00:33">

我想做的就是说

@user.events(roleName)

并获取与 roleName 关联的所有事件。

显然,仅考虑通过 Rolify 提供给我的东西,我无法做到这一点,因此我在我的用户模型上创建了一个方法来提供帮助:

  def events roleName=nil
    events_list = []

    self.roles.each do |role|
      unless roleName.nil?
        if role.name == roleName && role.resource_type == "Event"
          events_list.push(role.resource_id)
        end
      else
        events_list.push(role.resource_id)
      end
    end
    Event.find(events_list)
  end

我担心的是

  1. 这种方法在某种程度上违反了单一职责原则。
  2. 此方法需要多次数据库调用才能最终获得事件——一个到角色,然后另一个到事件。 (我对这种事情没有经验,所以我不确定它到底有多糟糕。)

有没有更好的方法来获取用户的事件,同时保持我的 Rolify 角色设置?

【问题讨论】:

    标签: ruby-on-rails ruby rolify


    【解决方案1】:

    是的,当您在 Rails 中有以下可能性时,这是一个坏主意:

    在你的用户模型中添加这个:

    has_many :events, through: :roles, source: :resource, source_type: 'Event'
    

    这样user.events 将返回用户的所有事件。对于特定角色的事件,您可以:

    user.events.where(roles: {name: role_name})
    

    Lastly, a suggestion: don't use camel-case names for methods, variables, or symbols.

    【讨论】:

    • 这引发了一个语法错误,内容为:“ArgumentError: Unknown key: :member。有效键是::class_name, :class, :foreign_key, :validate, :autosave, :table_name, :before_add , :after_add, :before_remove, :after_remove, :extend, :primary_key, :dependent, :as, :through, :source, :source_type, :inverse_of, :counter_cache, :join_table"
    • 是的,这是一个错字。密钥应该是source - 我已经更新了我的回复。
    • 另外,感谢您提供指向 Ruby 样式指南的链接。我一定会为此而努力。我目前正在阅读 Practical Object-Oriented Design in Ruby 并认为两者将齐头并进。
    • 我很好奇——如果我需要从视图中的多个位置访问此方法怎么办?在我看来可以写这个吗? user.events.where(roles: {name: role_name})
    • 没有。这将触发数据库查询并减慢视图的呈现速度。请记住:数据应该发送到已经生成的视图 - 否则当视图必须自己生成数据时速度会受到影响。您可以在控制器中执行相同的操作,将值存储在实例变量中,然后在视图中使用该实例变量(已获得值)。
    猜你喜欢
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多