在 Rails 中,我有一个名为
Post
的模型,其中有一个名为 columns
的字段。用户可以选择要显示的列。我在表单中使用以下代码行来执行此操作:
<%= form.collection_check_boxes(:columns, { "Title": "title", "Body": "body" }, :last, :first) %>
我使用它是为了简单地将用户想要显示的列存储在数据库的数组中。问题是我需要验证该数组以确保只能选择允许的列。为此,我对我的帖子模型进行了以下验证:
validate :validate_columns
def validate_columns
permitted = [ "title", "body" ]
unless columns.is_a?(Array) && columns.all?{ |c| permitted.include?(c) }
errors.add(:columns, :invalid)
end
end
这对于只允许所需的列来说效果很好,但是现在我无法在没有错误的情况下提交表单,因为 collection_check_boxes 帮助程序会自动向数组添加一个空字段来处理未选择复选框的情况。问题是这没有通过我的验证。
我已经阅读过有关 collection_check_boxes 的
include_hidden: false
选项,但是如果我使用它,用户将无法取消选择所有列。
那么,有人对我如何解决这个问题有任何想法,或者这种方法是否可行?
编辑:
这些是我控制器中的强参数:
def post_params
params.require(:post).permit(:title, :body, columns: [])
end
这是我的迁移:
def change
create_table :posts do |t|
t.string :title
t.text :body
t.string :columns, array: true, default: []
t.timestamps
end
end
因此,如果您有
nil
或空数组,您希望允许验证通过。所以基本上有两种选择:
您可以向
validate
调用添加一个防护,这样它仅在参数存在时运行:
validate :validate_columns, if: -> r { r.columns.present? }
# existing validate_columns method
或者您可以按原样保留该调用并将该逻辑移至您的验证方法:
validate :validate_columns
def validate_columns
return if colums.empty?
# ... the rest of your validation
end
我更喜欢后者,因为它将逻辑保留在一个地方,但这是一个主观的事情。