4

我想对模型用户和事件之间的这种关系进行建模。

因此,我从以下课程开始:

class User < ActiveRecord::Base
...
end

class Attendance < ActiveRecord::Base
# with columns user_id and event_id
...
end

class Event < ActiveRecord::Base
  has_many :attendances
  has_many :users, :through => :attendances
  ...
end

到目前为止一切正常:我可以分配用户并访问考勤。但是现在我想让状态发挥作用,这样我就可以区分例如“出席”、“无故缺席”……用户。我的第一次尝试是:

class Event < ActiveRecord::Base
  has_many :attendances
  has_many :users, :through => :attendances
  has_many :unexcused_absent_users, -> { where :state => 'unexcused' },
                                   :through => :attendances,
                                   :source => :user
  ...
end

(:source 必须指定,否则它会搜索一个属于名为 'unexcused_absent_users' 的关联) 这里的问题是,where-predicate 是在表 'users' 上评估的。

我不知道如何“正确”解决这个问题,而不为每个州引入新的连接表/模型。尤其是因为每个用户在每个事件中都只能处于一种状态,我认为使用一个出勤模型的解决方案是有意义的。

你有一个想法,如何做到这一点?

4

3 回答 3

4

您可以简单地缩小范围以查看正确的表格:

  has_many :unexcused_absent_users, -> { where(attendances: {state: 'unexcused'}) },
                               :through => :attendances,
                               :source => :user

更好的是,将此范围添加到出勤模型并将其合并到:

class Attendance < ActiveRecord::Base
  def self.unexcused
    where state: 'unexcused'
  end
end

class Event < ActiveRecord::Base
  has_many :unexcused_absent_users, -> { merge(Attendance.unexcused) },
                               :through => :attendances,
                               :source => :user      
end
于 2013-06-30T16:34:59.637 回答
1

这可能对你有用吗?

class Event < ActiveRecord::Base
  has_many :attendances
  has_many :users, :through => :attendances

  def unexcused_absent_users
    User.joins(:attendances)
      .where(:state => 'unexcused')
      .where(:event_id => self.id)
  end
end  

在 rails 3+ 中,方法与作用域基本相同,只是不那么混乱(在我看来),它们是可链接的

event = Event.find(xxxx)
event.unexcused_absent_users.where("name LIKE ?", "Smi%")
于 2013-06-30T15:36:21.170 回答
1

我找到了一种解决方法,但我仍然认为,这很难看。

class Event < ActiveRecord::Base
  has_many :user_attendances, :class_name => 'Attendance'
  has_many :users, :through => :user_attendances, :source => :user

  has_many :unexcued_absent_user_attendances, -> { where :state => 'unexcused'}, :class_name => 'Attendance'
  has_many :unexcused_absent_users, :through => :unexcued_absent_user_attendances, :source => :user
end

一般来说:对于我想要的每个状态,我都必须引入一个新的 has_many 关系,其中包含一个范围,并在此之上以及一个相应的 has_many-through 关系。

于 2013-06-30T15:32:41.610 回答