在文本字段中存储数组/哈希

时间:2016-03-09 17:29:46

标签: ruby-on-rails arrays ruby

我想在字符串字段中存储数组或哈希。该字段包含有关如何使用特定资源的说明。当一个人编辑该字段时,我想捕获日期和当前用户,并将它们与人输入的文本一起存储。我试图避免添加额外的字段只是为了捕获日期和当前用户。我想简单地添加一个4000字符的文本字段,并将其存储在那里。

看起来我需要序列化模型中的字段。但我正在努力解决如何将日期,当前用户和文本作为数组保存在单个字段中的问题,或者如果更有意义则将其保存为哈希。我创建了一个简单的CRUD应用程序来模拟我尝试做的事情,基于一个名为' product'的模型。下面是编辑页面,下面是控制器中的更新功能。我如何捕获当前日期和用户,并将其存储在'描述'领域?这会发生在编辑视图本身,还是应该发生在控制器的更新方法中?

edit.html.erb
<%= form_for @product do |f| %>
<p>
<%= f.label :name %><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :description %><br>
<%= f.text_area :description %>
</p>
<p>
<%= f.label :price %><br>
<%= f.text_area :price %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>

模型

class Product < ActiveRecord::Base
#validates  :name, :price , presence: true
serialize :description
end

更新方法

def update
@product = Product.find(params[:id])
if @product.update(product_params)
  redirect_to @product
else
  render 'edit'
end
end  

2 个答案:

答案 0 :(得分:1)

首先,我建议您采用这种方法,除非您有一个比“我试图避免添加额外字段以捕获日期和当前用户”更好的理由。如果您将date的字段和外键添加到user,将来管理和维护此数据会容易得多。如果product模型上存在这两个字段,那么上面的代码就可以正常工作。

话虽如此,有可能做到这一点。这是你可以做到的一种方式。

def update
  @product = Product.find(params[:id])
  combined_description = []
  combined_description.push(params[:description], params[:current_user], params[:date])

  # The next line returns a string representation of the array
  product_params[:description] = combined_description.to_s

  if @product.update(product_params)
    redirect_to @product
  else
    render 'edit'
  end
end 

然后,当您将来需要再次操作此数据时,您必须将描述字符串转换回数组,以便解析current_user和date。

def show
  @product = Product.find(params[:id])

  # next line returns [description, current_user, date]
  description_array = JSON.parse(@product.description) 
end

请参阅Array#to_s了解to_s方法文档。

同样,我不建议您遵循此方法,除非您有充分的理由这样做。如果只是将这些字段添加到产品模型中,您的生活将变得更加容易。

答案 1 :(得分:0)

尝试将此视图置于您的视图中会很笨拙,并且您的模型不了解current_user,因此您必须在控制器中为此设置一些代码。

我建议实际使用虚拟属性来显示/编辑实际的描述文字,所以在你的模型中:

serialize :description
def desc
  self.description? ? self.description[:text] : ""
end

然后在您的视图中,您将拥有该desc属性的字段:

= f.label :desc
= f.text_field :desc

然后在您的控制器中,您需要从参数中取出:desc并插入:description代替:

def product_params
  p = params.require(:product).permit(:name, :price, :desc)
  p.merge description: { text: p.delete(:desc), user: current_user, date: Date.today }
end