模型的复选框实现逻辑

时间:2014-02-27 19:13:56

标签: ruby-on-rails ruby checkbox ruby-on-rails-4

我在为模型实现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来阻止这种行为吗?

1 个答案:

答案 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组,请不要忘记加急加载。