有没有更好的方法来获取这些数据?

时间:2009-09-14 14:50:24

标签: ruby-on-rails activerecord

摄影师“有很多”客户。

客户“have_many”事件。

如果用户是摄影师,是否有更好的方法在此处指定@events?

  def index
    if @current_user.photographer?
      @events = []
      @current_user.clients.each do |client|
        @events << client.events
      end
    else
      @events = @current_user.events
    end
  end

修改:更多代码

# user.rb
class User < ActiveRecord::Base

  has_many :client_associations, 
      :foreign_key => 'photographer_id', 
      :class_name => 'Association', 
      :dependent => :destroy
  has_many :clients, :through => :client_associations

  has_one :photographer_association, 
    :foreign_key => 'client_id', 
    :class_name => 'Association', 
    :dependent => :destroy
  has_one :photographer, :through => :photographer_association

  has_many :events

  def photographer?
    self.role == 'photographer'
  end

end

# association.rb
class Association < ActiveRecord::Base
  belongs_to :client, :class_name => "User"
  belongs_to :photographer, :class_name => "User"
end

# event.rb
class Event < ActiveRecord::Base
  belongs_to :user
  has_many :images      
end

正如您所看到的,我的用户都在一个模型中,其中包含一个名为“role”的字段。

2 个答案:

答案 0 :(得分:2)

从db的角度来看,您应该立即加载所有事件而不会出现N + 1问题。

  def index
    if @current_user.photographer?
      @events = @current_user.clients.find(:all, :include => :events).map(&:events).flatten
    else
      @events = @current_user.events
    end
  end

答案 1 :(得分:0)

这种逻辑,恕我直言,将在模型层上更正确地设置。

你可以创建一个新的模型方法,比如User模型上的current_events,并在那里移动你的逻辑:

def current_events
    if self.photographer?
         self.clients.find(:all, :include => :events).map(&:events).flatten
    else
         self.events
    end
end

然后,在你的控制器上你可以添加

def index
  @events = @current_user.current_events
end

因此,你的逻辑被封装在你的模型上(以后我可以改进,添加了复杂性,经过测试),你的控制器不需要知道(并关心)它是什么,只是调用并显示用户的current_events。