我在为模型实现checkbox
逻辑时遇到了麻烦。模型skills
中有一个名为Resume
的字段,它通过checkboxes
接受多个值。
Resume
模型架构如下:
create_table :resumes do |t|
t.string :name, null: false
t.text :bio
t.string :skills
t.timestamps
end
在视图中,此处的复选框特定于我的代码:
<% skills = ["Ruby", "Perl", "Java", "C", "C++"] %>
<div class="form-group">
<% skills.each do |skill| %>
<%= check_box_tag "resume[skills][]", skill %> <%= skill %>
<% end %>
</div>
在控制器中:
def resume_params
params[:resume][:skills] = params[:resume][:skills].join(",")
params.require(:resume).permit(:name, :bio, :skills)
end
我从表单返回一个skills
数组。由于我已将skills
声明为数据库中的字符串类型,因此我将comma
中存储在数组中的已检查值加入数据库之前。我这样做的原因是因为我不知道data type
Array
以便将技能直接存储在数据库中。
这是在数据库中存储复选框值的正确方法还是可以更好的方式实现?
为了在数据库中创建/更新,分割和加入skills
(复选框值)似乎是不必要的工作。
修改
使用我的方法(非序列化),当我在简历中更新bio
字段时,这就是它的更新方式
SQL(0.2ms)UPDATE“恢复”SET“bio”=?,“updated_at”=?哪里 “恢复”。“id”= 20 [[“bio”,“这是我的生物”],[“updated_at”,周四, 2014年2月27日19:27:06 UTC +00:00]]
使用PinnyM建议的 serialize
方法,
class Resume < ActiveRecord::Base
....
serialize :skills
end
当我在简历中更新bio
字段时,这是其更新的
SQL(0.2ms)UPDATE“恢复”SET“bio”=?,“updated_at”= ?, “技能”=?在哪里“恢复”。“id”= 20 [[“bio”,“这是我的新生物”], [“updated_at”,星期四,2014年2月27日20:18:31 UTC +00:00],[“技能”, “--- \ n- Java \ n-C \ n- Ruby \ n”]](0.6ms)提交事务
注意skills
再次更新的区别,即使我没有对其进行任何更改,但是我的方法skills
没有更新,因为我没有对它进行任何更改。我想知道为什么行为的差异?我有什么选择可以传递给serialize
来阻止这种行为吗?
答案 0 :(得分:2)
使用简历模型中的serialize
宏来帮助解决此问题:
serialize :skills, Array
使用此功能,您可以将技能参数设置为数组,ActiveRecord将为您执行序列化/反序列化。
至于执行的常量UPDATE,这是我在下面提供的链接中讨论的持续问题。如果这种行为困扰你,我能看到的最简单的解决方法是@ M.G.Palmer的回答here的变体。它的要点是将其分解为存储此数组的简单模型:
class Resume < AR::Base
has_one :skill_store
delegate :skills, to: :skill_store, allow_nil: true
class SkillStore < AR::Base
belongs_to :resume
serialize :skills, Array
由于此数据现在位于单独的表中,因此如果收集需要skills
数据的Resume组,请不要忘记加急加载。