Ruby on rails 在Rails 4中,多作用域具有多通关系

Ruby on rails 在Rails 4中,多作用域具有多通关系,ruby-on-rails,activerecord,scope,has-many-through,Ruby On Rails,Activerecord,Scope,Has Many Through,我想在模型用户和事件之间建立这样的关系模型 因此,我从以下课程开始: 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, :thro

我想在模型用户和事件之间建立这样的关系模型

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

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用户:出席人数
...
结束
到目前为止一切正常:我可以分配用户和访问出席人数。但现在我想让国家发挥作用,这样我就可以区分“出席”、“无故缺席”。。。用户。我的第一次尝试是:

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
class事件:出席人数
有很多:未经许可的用户,>{where:state=>'unexecuted'},
:至=>:出席人数,
:source=>:user
...
结束
(:必须指定源,否则它将搜索名为“未经许可的\u缺席\u用户”的属于关联) 这里的问题是,where谓词是在表“users”上计算的

我不知道如何“正确”解决这个问题,而不为每个州引入新的联接表/模型。特别是因为每个用户对于每个事件都可以处于一种状态,所以我认为使用一种出席模型的解决方案是有意义的


你有什么好主意吗?我找到了一个解决办法,但我仍然认为,这很难看

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
class事件“出席人数”
有很多:用户,:通过=>:user\u出席人数,:source=>:user
有很多:未经许可的用户出席,->{where:state=>'unexecuted'},:class\u name=>'attention'
有很多:未经许可的缺席用户,:通过=>:未经许可的缺席用户,:来源=>:用户
结束

总的来说:对于我想要的每一个州,我都必须引入一个新的有多个范围的关系,除此之外还有一个相应的有多个范围的关系。

这可能适合你

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  

您只需缩小范围即可查看正确的表格:

  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
课堂出勤{merge(attention.unexecuted)},
:至=>:出席人数,
:source=>:user
结束

这有一个缺点,即不可写。在我看来,添加另一个方法
unexecuted\u-abent\u-users=array
并不是“railsy”:\n上面的方法
unexecuted\u-abent\u-users
返回的是
ActiveRelation
对象,而不是数组;让“有状态”集合可写对我来说不是个好主意?您可以使用特定的方法来更改状态,即
event.缺席\u但\u不\u原谅!(用户)
用户。不免除(事件)
-猜测这归结为个人偏好在
考勤
类中使用合并命名方法是干净的。但不幸的是,这不起作用。
事件
类缺少名为
出席人数
的关联,出于某种原因,该关联将为只读。我不知道为什么,但当通过它保存时,作用域中设置的
状态
丢失/忽略/nil。@MarioZigliotto:“事件类缺少名为Attentings的关联…”-OP在包含行
事件
的初始代码中编写了许多:Attentings
。你能解释一下你的意思吗?在OP给出的解决方案中,他提到了
:user_attentations
-也许协会名称被更改了?我遇到了一个非常类似的问题,并在Rails项目()上记录了一个问题。我不能百分之百确定这是一个真正的问题或用户错误,但我最终做了一个类似于你的解决方法。使用此解决方法时,我遇到了一些奇怪的问题。例如,我敢打赌这样做:
Event.create!(标题:“foo”,未经许可的用户ID:[1,2,3])
导致
状态
属性设置为
nil
。如果你想在github上讨论我的问题,或者对你的方法有任何进一步的反馈,我很乐意听到。我忘了提到我使用了
Event
创建的例子,因为我认为这与
eventscoontroller#create
在用户添加事件的页面上同时收到的帖子非常相似标记那些无故缺席的人。(例如,像一堆带有学生姓名的复选框)
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