Ruby on rails 如何使逗号分隔的ID变成rails参数中的数组,如ids[]将

Ruby on rails 如何使逗号分隔的ID变成rails参数中的数组,如ids[]将,ruby-on-rails,Ruby On Rails,因此,通常的方法是使用多个名为“obj_ids[]”的输入字段,然后rails中的值神奇地将它们压缩到一个数组中 rails是否有一些秘密的方法,可以用一个字段交替地执行此操作 我需要将输入字段从实际表单中分离出来,所以现在我基本上是将它们全部捕获,并在它们上运行JS连接,以作为单独表单中的一个字段发送。我可以将它们全部复制为隐藏字段,但这似乎有点过分。当然也可以在控制器中进行拆分,但我很好奇是否有其他方法。我不认为有其他方法,我以前也研究过其他情况 对于您的情况,如果我理解正确的话,您正在使用

因此,通常的方法是使用多个名为“obj_ids[]”的输入字段,然后rails中的值神奇地将它们压缩到一个数组中

rails是否有一些秘密的方法,可以用一个字段交替地执行此操作


我需要将输入字段从实际表单中分离出来,所以现在我基本上是将它们全部捕获,并在它们上运行JS连接,以作为单独表单中的一个字段发送。我可以将它们全部复制为隐藏字段,但这似乎有点过分。当然也可以在控制器中进行拆分,但我很好奇是否有其他方法。

我不认为有其他方法,我以前也研究过其他情况

对于您的情况,如果我理解正确的话,您正在使用JS构建表单并使用JS提交表单,这取决于您是使用多个值在一个输入中混合在一起(这将变成一个URL查询参数),用逗号分隔,还是单独的字段/参数分隔

我会选择单独的字段/参数

否则,在控制器端,您可以在before_过滤器中执行此操作,而不仅仅是在action方法中,甚至可以在应用程序控制器上应用于所有操作的before_过滤器中执行此操作,您甚至可以让before_过滤器mutate Rails自己的参数散列

before_filter :split_commas
def split_commas
   params[:my_field] = params[:my_field].split(",")
end

这应该是可行的,尽管像这样对params散列进行变异是导致我产生如此多令人沮丧的bug的原因,我不愿意这样做

根据您的具体需求,在rails中有很多方法可以实现这类功能

对@jrochkind提到的参数进行黑客攻击是一种方法,但还有几种更优雅的解决方案

在模型中创建虚拟属性

class SomeModel
  attr_reader :my_field

 def my_field= value_as_comma_delimited_string
   # here the the_field_i_really_want_set is an array type which is supported in mongo and postgres for exampld
   self.the_field_i_really_want_set = value_as_comma_delimited_string.split(",")
 end
end
您可以在before_验证回调中执行基本相同的操作。在这种情况下,您不需要创建访问器

class User < ActiveRecord::Base
  before_validation :normalize_name, on: :create


 protected
 def normalize_name
  self.name = self.name.downcase.titleize # or whatever transformation you need
 end

按照@hraynaud的建议,向模型中添加另一个setter(或覆盖现有的setter)是一种可能性。然而,在我看来,支持一些非标准的输入格式更像是控制器的职责,而不是模型的职责。因此,我不会把这种逻辑放在模型中

相反,我将介绍另一个控制器的方法,该方法返回预处理的参数。在强参数下工作得很好

protected

def preprocessed_params
  p = params.deep_dup
  p[:obj_ids] = p[:obj_ids].split(",") if p[:obj_ids]
  p
end

def permitted_params
  preprocessed_params.permit(:obj_ids => [])
end

可以使用
alias\u method\u chain
进一步修改此代码段,以便通过
params
访问预处理的参数,而原始参数则保存在
params\u中,而不进行预处理。我有一个特定的功能,虽然它是在多个模型和多个控制器上,所以我特别想尽量避免在这些东西上编写一堆代码来处理它。最后,我决定简单地将JS中的字段复制到新表单中。在params级别上做一些事情更符合我的要求,但我不认为我会想要破解它。不过,这将是一个有趣的解决方案。
protected

def preprocessed_params
  p = params.deep_dup
  p[:obj_ids] = p[:obj_ids].split(",") if p[:obj_ids]
  p
end

def permitted_params
  preprocessed_params.permit(:obj_ids => [])
end