ruby-on-rails - 在 Postgres 中使用 Rails 数组

标签 ruby-on-rails postgresql ruby-on-rails-4 strong-parameters ruby-on-rails-4.1

我有一个名为 content 的 postgres 列,它是一个数组。

但是当我尝试以一种形式使用它时,我得到:

无法将 ActionController::Parameters 转换为文本

尽管输出看起来很不错:

{"utf8"=>"✓",
 "_method"=>"patch",
 "authenticity_token"=>"NkK4BggxknfEn0A8shTs06xmesERaZdYtZdl9oEEUTk=",
 "notification_template"=>{"content"=>{"0"=>"Join us {{event_time}} {{{twitter_name}}} to win Big! hint: {{{question}}} #quiz {{location_tags}} {{url}} sdfsdfsdf"}},
 "commit"=>"Update Notification template",
 "id"=>"25"}

强参数

params.require(:notification_template).permit(:name, :content => {})

路线

resources :notification_templates do
  get 'edit/:id', to: 'notification_templates#edit_content', as: 'edit_content'
end

Controller

  def edit_content
    @notification_template = NotificationTemplate.find(params[:notification_template_id])
  end

  def update
    if @notification_template.update(notification_template_params)
      redirect_to admin_notification_template_path(@notification_template), notice: 'Social message was successfully updated.'
    else
      render action: 'edit'
    end
  end

我的表格

url 看起来像:/notification_templates/25/edit_content/7 # 自定义操作,但使用正常更新

<%= simple_form_for([:admin, @notification_template]) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.simple_fields_for :content do |fields| %>
        <%= fields.input params[:id], input_html: { value: @notification_template.content[params[:id].to_i] } %>
    <% end %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>

<% end %>

数据库列

add_column :notification_templates, :content, :text, array: true, default: []

最后,我不确定添加它的约定。以上工作正常,但我也注意到其他可能性,例如

add_column :notification_templates, :content, :text, array: true, default: []
add_column :notification_templates, :content, :sting, array: true, default: []
add_column :notification_templates, :content, :text, array: true, default: {}

我选择第一个是因为字符串不允许包含我最终可能需要的那么多字符,而且文本更方便。也是 []{}'{}'

的默认值

但是在 postgres 中是看到 content text[] DEFAULT '{}'::text[]

日志

Started PATCH "/admin/notification_templates/25" for 127.0.0.1 at 2014-11-28 14:25:43 +0100
Processing by Admin::NotificationTemplatesController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"NkK4BggxknfEn0A8shTs06xmesERaZdYtZdl9oEEUTk=", "notification_template"=>{"content"=>{"4"=>"{{{question}}} Study up and stop by {{{twitter_name}}} {{event_time}} for a #quiz {{location_tags}} {{url}} sdfsdfsdf"}}, "commit"=>"Update Notification template", "id"=>"25"}
  User Load (0.9ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 1  ORDER BY "users"."id" ASC LIMIT 1
  NotificationTemplate Load (0.5ms)  SELECT  "notification_templates".* FROM "notification_templates"  WHERE "notification_templates"."id" = $1 LIMIT 1  [["id", 25]]
   (0.3ms)  BEGIN
   (0.3ms)  ROLLBACK
Completed 500 Internal Server Error in 54ms
Reporting exception: can't cast ActionController::Parameters to text

TypeError (can't cast ActionController::Parameters to text):
  app/controllers/admin/notification_templates_controller.rb:40:in `update'


  Rendered /Users/holden/.rvm/gems/ruby-2.0.0-p481@questionone-2.0/gems/actionpack-4.1.7/lib/action_dispatch/middleware/templates/rescues/_source.erb (1.1ms)
  Rendered /Users/holden/.rvm/gems/ruby-2.0.0-p481@questionone-2.0/gems/actionpack-4.1.7/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.0ms)
  Rendered /Users/holden/.rvm/gems/ruby-2.0.0-p481@questionone-2.0/gems/actionpack-4.1.7/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.4ms)
  Rendered /Users/holden/.rvm/gems/ruby-2.0.0-p481@questionone-2.0/gems/actionpack-4.1.7/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (27.5ms)

更新

我还观察到更新数组类型字段在控制台中没有按预期工作。

例如。如果我尝试更新数组的成员,something = record.content[2] = 'blah' 它似乎可以工作。但是当我保存记录时它不会更新它。

最佳答案

是的,Rails postgres 数组仍然有点不稳定。 Hstore 更容易一些。

与通过表单依赖标准 Rails 行为相比,通过虚拟属性明确地做您想做的事情可能会更好。

例如。

def content_member=(member)
    unless member.blank?
        self.content_will_change!
        self.content[member.keys.first.to_i] = member.values.first
    end
end

如果您要更新数组的成员,您还需要让 Rails 知道,这就是它在控制台中不起作用的原因。

这里有完整的解释:

Rails 4 Postgresql array data-type: updating values

关于ruby-on-rails - 在 Postgres 中使用 Rails 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27189366/

相关文章:

ruby-on-rails - Rails 不加载 application.html.erb,而是加载 View stub

ruby-on-rails - Heroku "at=error code=H10 desc="应用程序崩溃“method=GET path=/favicon.ico”

ruby-on-rails - ActiveRecord 触摸(:column) always also updates :updated_at

python - TransactionManagementError - 当 'atomic' block 处于事件状态时,这是被禁止的

ruby-on-rails-4 - before_save 回调是按照 rails 声明的顺序执行的

ruby-on-rails - Rails 和外键

sql - 在 SQL 中计算和划分来自多个列的不同值对

java - 在 Hibernate 中的存储库和服务中编写查询

html - 如何将额外数据添加到 simple_form 自定义包装器 :icon

ruby-on-rails - 没有路由匹配 GET/sign_up,但我可以访问该页面?