我正试图弄清楚如何在一个视图中显示来自两个独立模型的内容。
我有个人资料,工作和资格模型。在配置文件视图中,我想显示配置文件,作业和资格的单个时间轴,按时间顺序排序。
我可以从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
我不确定上述方法和范围是否正确列出。我发现很难学会如何做到这一点。
我的下一步是如何弄清楚如何以正确的顺序组合它们,即:
我的想法是,尝试编写此方法的正确位置在配置文件模型中。
这是我的尝试(在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| %>
任何人都可以提供有关如何编码的任何帮助吗?我已经写了这些方法和范围,但我不认为它是正确的。我唯一知道的是它的错误,但我对如何设置它起作用感到困惑。
答案 0 :(得分:0)
如果我了解您的需求,您的算法可能就像:
data = [profile.current_job]
。data = data.concat(profile.qualifications.pending)
。答案 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