Rails 4 - 在一个部分

时间:2016-05-31 00:34:40

标签: ruby-on-rails ruby model-view-controller methods scope

我正试图弄清楚如何在一个视图中显示来自两个独立模型的内容。

我有个人资料,工作和资格模型。在配置文件视图中,我想显示配置文件,作业和资格的单个时间轴,按时间顺序排序。

我可以从SO上找到的最接近的例子是:Rails: Combining two different ActiveRecord collections into one

我正在考虑如何做到这一点。

模型关联是:

个人资料has_many:jobs,has_many:qualifications

每个职位和资格都属于:个人资料

Jobs表有:

t.integer  "profile_id"
t.string   "company"
t.date     "start_date"
t.date     "end_date"
t.string   "title"
t.text     "description"
t.boolean  "current_job"
t.datetime "created_at",  null: false
t.datetime "updated_at",  null: false

资格表有:

t.string   "level"
t.string   "title"
t.string   "institution"
t.integer  "year_earned"
t.datetime "created_at",  null: false
t.datetime "updated_at",  null: false
t.integer  "profile_id"
t.boolean  "pending"

在我的个人资料视图中,这是我正在尝试的内容:

我不想要:创建at作为排序值,但我一直在考虑在何处以及如何定义一个函数来确定作业是否是current_job,如果是,则将其固定在顶部时间表,类似地,如果资格是:待定,则在当前工作(如果有)之后固定在顶部。

然后,每个剩余的工作和资格应按时间顺序排序:end_date如果是工作,或者:year_earned如果是资格。

然后,它们应该合并并显示在一个视图中。

这是我尝试编写方法:

在Job.rb

   class Job < ActiveRecord::Base


  # --------------- associations
  belongs_to :profile


  # --------------- scopes


  timeline_scope :previous_jobs order('end_date DESC')


  # --------------- class methods

  def period
    [self.start_date.strftime('%B %Y'), end_date.strftime('%B %Y')].compact.join(" - ")
  end

  def current_job?
    if self.curent_job == true
      [self.start_date.strftime('%B %Y'), '(continuing)'].join(', ')
    end  
  end

  def previous_jobs
    if self.curent_job == false
      self.period
    end  
  end

在资格模型中,我有:

    class Qualification < ActiveRecord::Base

  # --------------- associations
  belongs_to :profile

  #to do - add relationship with universities

  # --------------- scopes


  scope :pending, -> { where(pending: true) }
  scope :completed_award, ->{ order('year_earned DESC')}


  # --------------- class methods

  def completed_award
    if self.pending == false
      [title, institution, year_earned].join(', ')
    end  
  end

  def current_study
    [title, institution, year_earned, '(currently studying)'].join(', ')
  end


end

我不确定上述方法和范围是否正确列出。我发现很难学会如何做到这一点。

我的下一步是如何弄清楚如何以正确的顺序组合它们,即:

  1. 如果有当前工作,那么首先是
  2. 如果有下一个待定资格
  3. 如果有先前的工作和资格,他们会合并,然后按时间顺序列出。
  4. 我的想法是,尝试编写此方法的正确位置在配置文件模型中。

    这是我的尝试(在profile.rb中):

    def timeline_list
        self.job.current_job?
        self.qualification.current_study.any?
        combined = self.job.previous_jobs.concat( Qualification.completed_award ).sort_by(&:timeline_date)
      end
    
    
    
        def timeline_date_historic
        if self.job (:end_date.strftime('%Y'))
        elsif self.qualification (:year_earned)
        end
      end
    
      def timeline_date_current
        self.job.current_job? && self.qualifiction.pending.any?
      end
    

    我的最后一步是在简介中写一下:

    <% profile.combined = ( Profile.timeline_date_historic + Profile.timeline_date_current).each do |timeline| %>
    

    任何人都可以提供有关如何编码的任何帮助吗?我已经写了这些方法和范围,但我不认为它是正确的。我唯一知道的是它的错误,但我对如何设置它起作用感到困惑。

2 个答案:

答案 0 :(得分:0)

如果我了解您的需求,您的算法可能就像:

  1. 查找个人资料
  2. 获取当前作业并将其放入列表data = [profile.current_job]
  3. 获取待定资格并连接到列表。例如:data = data.concat(profile.qualifications.pending)
  4. 创建另一个列表并将所有其他资格和作业放入其中,然后按您想要的字段对其进行排序。 Array#sort方法应该有所帮助。
  5. 毕竟,将第二个列表连接到第一个列表。

答案 1 :(得分:0)

虽然组合两个不同的范围可能会在尝试访问它们时导致问题。 (例如,列名将从对象更改为对象)

你可以做这样的事情

#app/models/job.rb
class Job < ActiveRecord::Base
  belongs_to :profile

  scope :current_jobs, -> {where(current_job: true)}
  scope :job_order, -> { order('end_date asc') }

end

#app/models/qualification.rb
class Qualification < ActiveRecord::Base
  belongs_to :profile

  scope :pending_qualifications, -> {where(pending: true)}
  scope :qualifications_order, -> { order('year_earned asc') }


end

#app/models/profile.rb
class Profile < ActiveRecord::Base
  has_many :jobs
  has_many :profiles


  def self.time_line
    #joining the scops
    # you may change the order as you wish 
    Job.current_jobs +
    Qualification.pending_qualifications +
    Job.job_order +
    Qualification.qualifications_order
  end
end

在您看来,您可以将其称为

<%= Profile.time_line %>

HTH