ActiveRecord - 在组模型中查找下一个用户

时间:2012-05-16 08:52:20

标签: ruby-on-rails ruby ruby-on-rails-3 activerecord

我有四种用户模型:ZoneProductUserGroup 我想选择User可以在Product中销售Zone的内容,这是Group所做的事情,与User有多对多关系,一个Product和一个Zone的外键。所以每对区域/产品我有一组。我还需要在多对多关系上设置自定义属性,因此我使用has_many :through Sell(我无法找到更好的名称来描述GroupUser之间的关系。 所以我最终得到了5个模型:ZoneProductUserGroupSell

它工作正常,但现在我需要选择Group中可用的下一个用户。 我正在考虑利用Sell.id找到分配给具有更高id的同一组的用户,如果不存在则再次选择第一个(这允许我创建一个环链)。 使用Group.next_user方法会很有用。

不幸的是我无法弄清楚如何做到这一点,我需要帮助才能找到该组中的下一个用户(如果没有更多用户,则需要第一个用户)。

按照所有模型的模型代码:

################
# models/group.rb
################
class Group < ActiveRecord::Base
  has_many :sells
  has_many :users, :through => :sells

  belongs_to :zone
  belongs_to :product
  attr_accessible :priority, :product_id, :user_ids, :zone_id
end

################
# models/zone.rb
################
class Zone < ActiveRecord::Base
  belongs_to :location
  has_many :cities
  has_many :groups

  attr_accessible :name, :location_id
  validates :location, :presence => true
end

################
# models/user.rb
################
class User < ActiveRecord::Base
  after_create :create_calendar
  before_destroy :destroy_calendar
  belongs_to :location
  belongs_to :mall
  has_one :event_calendar

  has_many :sells
  has_many :groups, :through => :sells

  # Include default devise modules. Others available are:
  # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable, :registerable,
  # :recoverable, :rememberable,
  devise :database_authenticatable, :trackable,
         :validatable, :authentication_keys => [:username]

  # Setup accessible (or protected) attributes for your model
  attr_accessible :username, :password, :password_confirmation, :remember_me, :name,
                  :surname, :role, :location_id
  # attr_accessible :title, :body

  ROLES = %w[Admin Agente Hostess HostessAdmin]

  validates_uniqueness_of :username, :case_sensitive => false
  validates :username, :presence => true
  validates_presence_of :role, :name, :surname, :location_id
  validates :location, :presence => true
    validates :role, :inclusion => { :in => ROLES, :message => "%{value} non è un ruolo valido." }

  def display_name
      "#{self.name} #{self.surname}"
  end

  def has_role?(role)
    # convert the role string to a sybmol
    self.role.downcase.gsub(/\s+/, "_").to_sym == role
  end

  private
  def create_calendar
    if self.has_role? :agente
      calendar = EventCalendar.new({:user_id => self.id})
      calendar.save()
    end
  end

  def destroy_calendar
    if self.has_role? :agente
      calendar = EventCalendar.find_by_user_id(self.id)
      calendar.destroy()
    end
  end

  def email_required?
    false
  end

  def email_changed?
    false
  end
end

################
# models/product.rb
################
class Product < ActiveRecord::Base
  after_create :create_groups
  before_destroy :destroy_groups
  attr_accessible :name

  def create_groups
    for zone in Zone.all
      group = Group.new({:zone_id => zone.id, :product_id => self.id})
      group.save()
    end
  end

  def destroy_groups
    for zone in Zone.all
      group = Group.find_by_product_id(self.id)
      group.destroy
    end
  end
end

################
# models/sell.rb
################
class Sell < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
end

你可以帮助我完成这项工作吗?谢谢!

1 个答案:

答案 0 :(得分:1)

如果我说得对,请将其添加到您的用户模型

scope :next, lambda { |p| {:conditions => ["id > ?", p.id], :limit => 1, :order => "id"} }

这是你的小组模特

def self.next_user
  return User.first if Group.users.blank?
  next_user = User.next(Group.users.last).first
  return next_user || Group.users.first
end

这应该可以解决问题。我没有为此编写测试,所以你应该测试它:)