[英]How to iterate through a Rails model's nested attributes?
I have a collection of models: Users, Cvs, Skills, Educations, & Experiences. 我收集了以下模型:用户,简历,技能,教育和经验。
# models/user.rb
class User < ApplicationRecord
has_one :cv
has_many :skills, through: :cv, inverse_of: :user
has_many :educations, through: :cv, inverse_of: :user
has_many :experiences, through: :cv, inverse_of: :user
...
end
# models/cv.rb
class Cv < ApplicationRecord
belongs_to :user
has_many :skills
has_many :educations
has_many :experiences
...
end
# models/skill.rb
class Skill < ApplicationRecord
belongs_to :cv
belongs_to :user, inverse_of: :skill
end
# models/education.rb
class Education < ApplicationRecord
belongs_to :cv
belongs_to :user, inverse_of: :education
end
# models/experience.rb
class Experience < ApplicationRecord
belongs_to :cv
belongs_to :user, inverse_of: :experience
end
So, basically, a user
has 1 cv
and many skills
, educations
, and experiences
that are nested in that cv
因此,基本上,一个
user
拥有1个cv
,并且嵌套在该cv
许多skills
, educations
和experiences
A Cv has many attributes other than the nested skills
, educations
, and experiences
. 简历除了嵌套的
skills
, educations
和experiences
,还具有许多属性。
How can I iterate through all of the attributes in a Cv, including the nested ones? 如何遍历Cv中的所有属性,包括嵌套属性? I tried this:
我尝试了这个:
@user = User.new
@user.build_cv
@user.cv.educations.build
@user.cv.experiences.build
@user.cv.skills.build
@user.cv.attributes.each_pair do |attr, value|
puts "#{attr}: #{value}"
end
But this just lists the attributes that are directly in the Cv model and not the attributes for the Cv's education
, skill
, and experience
. 但这只是列出了直接在Cv模型中的属性,而不是Cv的
education
, skill
和experience
的属性。 What I eventually need to do is iterate through the Cv attributes and it's nested attributes searching for blank values in order to make sure a Cv has been completed. 我最终需要做的是遍历Cv属性,并且嵌套属性搜索空白值,以确保Cv已完成。 I could do that with a simple
.blank?
我可以用一个简单的
.blank?
来做到这一点.blank?
on each attribute if I could just figure out how to iterate through them all. 关于每个属性,如果我能弄清楚如何遍历它们的话。
So far, this is the most concise way I came up with to do it, I was just hoping that there was a built-in helper method for something like this: 到目前为止,这是我想出的最简洁的方法,我只是希望有一个内置的帮助器方法来执行以下操作:
def is_complete?
user = current_user
user.cv.attributes.each do |attr|
return false if attr.blank?
end
user.cv.skills.each do |skill|
skill.attributes.each do |sa|
return false if sa.blank?
end
end
user.cv.educations.each do |edu|
edu.attributes.each do |ea|
return false if ea.blank?
end
end
user.cv.experiences.each do |exp|
exp.attributes.each do |exa|
return false if edu.blank?
end
end
true
end
You can use reflect_on_all_associations
您可以使用
reflect_on_all_associations
Cv.reflect_on_all_associations(:has_many).map(&:name).each do |attr|
if @user.cv.send(attr).blank?
# do something
end
end
If you want to check individual attribute elements... 如果要检查单个属性元素...
Cv.reflect_on_all_associations(:has_many).map(&:name).each do |attr|
@user.cv.send(attr).each do |item|
if item.blank?
# do something
end
end
end
or if you're looking at checking each attribute of each item... 或者如果您要检查每个项目的每个属性...
If you want to check individual attribute elements... 如果要检查单个属性元素...
Cv.reflect_on_all_associations(:has_many).map(&:name).each do |attr|
@user.cv.send(attr).each do |item|
item.attributes.each_pair do |subattr, value|
puts "#{item.class}.#{subattr}: #{value}"
end
end
end
But a more natural way to do this would be to put validations on the association models. 但是,更自然的方法是将验证放在关联模型上。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.