【问题标题】:Rails 4 form: checkbox not saving value to databaseRails 4表单:复选框未将值保存到数据库
【发布时间】:2016-01-15 14:05:20
【问题描述】:

我有一个带有以下 Post 模型的 Rails 4 应用程序:

create_table "posts", force: :cascade do |t|
    t.integer  "calendar_id"
    t.date     "date"
    t.time     "time"
    t.string   "subject"
    t.string   "format"
    t.text     "copy"
    t.datetime "created_at",         null: false
    t.datetime "updated_at",         null: false
    t.string   "image_file_name"
    t.string   "image_content_type"
    t.integer  "image_file_size"
    t.datetime "image_updated_at"
    t.string   "short_copy"
    t.integer  "score"
    t.boolean  "facebook"
    t.boolean  "twitter"
    t.boolean  "instagram"
    t.boolean  "pinterest"
    t.boolean  "google"
    t.boolean  "linkedin"
    t.boolean  "tumblr"
    t.boolean  "snapchat"
    t.string   "approval"
  end

必须允许用户决定post.facebooktrue 还是false,这就是:facebookboolean 的原因。

然后,我创建了以下表单,以允许用户实际制作post.facebook truefalse

<%= form_for [@calendar, @calendar.posts.build], html: { multipart: true } do |f| %>
  <% if @post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
      <% @post.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <hr>

  <div class="field">
    <h3>Post details</h3>
    <p>
      <%= f.label :date %>
      <%= f.date_select :date %>
    </p>
    <p>
      <%= f.label :time %>
      <%= f.time_select :time %>
    </p>
    <p>
      <%= f.label :format %>
      <%= f.select :format, ['Simple Status', 'Image', 'Link', 'Video'] %>
    </p>
    <hr>
    <h3>Post content</h3>
    <p>
      <%= f.label :subject %>
      <%= f.text_field :subject %>
    </p>
    <p>
      <%= f.label :copy %>
      <%= f.text_area :copy %>
    </p>
    <p>
      <%= f.label :short_copy, "Short copy (Twitter only)" %>
      <%= f.text_area :short_copy %>
    </p>
    <hr>
    <h3>Social channels</h3>
    <p>
      <%= f.label_tag(:facebook, "Facebook" )%>
      <%= f.check_box_tag(:facebook) %>
    </p>
    <p>
      <%= f.label_tag(:twitter, "Twitter") %>
      <%= f.check_box_tag(:twitter) %>
    </p>
    <p>
      <%= f.label_tag(:instagram, "Instagram") %>
      <%= f.check_box_tag(:instagram) %>
    </p>
    <p>
      <%= f.label_tag(:pinterest, "Pinterest") %>
      <%= f.check_box_tag(:pinterest) %>
    </p>
    <p>
      <%= f.label_tag(:google, "Google+") %>
      <%= f.check_box_tag(:google) %>
    </p>
    <p>
      <%= f.label_tag(:linkedin, "LinkedIn") %>
      <%= f.check_box_tag(:linkedin) %>
    </p>
    <p>
      <%= f.label_tag(:tumblr, "Tumblr") %>
      <%= check_box_tag(:tumblr) %>
    </p>
    <p>
      <%= f.label_tag(:snapchat, "Snapchat") %>
      <%= f.check_box_tag(:snapchat) %>
    </p>
    <hr>
    <h3>Image</h3>
    <p>
      <%= f.label :image %><br>
      <%= f.file_field :image %>
    </p>
  </div>
  <hr>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

我确实清理了posts_controller.rb 中的所有参数:

def post_params
  params.require(:post).permit(:date, :time, :subject, :format, :copy, :image, :short_copy, :score, :facebook, :twitter, :instagram, :pinterest, :google, :linkedin, :tumblr, :snapchat, :approval)
end

问题是,每当我尝试create 新帖子或edit 现有帖子,并选中:facebook 复选框,然后保存帖子时,该值仍设置为nil

————

更新:这是我尝试更新帖子时的服务器日志:

Started PATCH "/posts/2" for ::1 at 2015-10-16 11:13:38 -0700
Processing by PostsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"gqhmCHecVEJdqvOE18HQTEVk+jlcJ9pBi1hYJ+7GQuXHUW2VbDyZggDlCx9uKddI+iCXkd1yhrW9RWZXv4/oUw==", "post"=>{"date(1i)"=>"2015", "date(2i)"=>"9", "date(3i)"=>"22", "time(1i)"=>"2000", "time(2i)"=>"1", "time(3i)"=>"1", "time(4i)"=>"08", "time(5i)"=>"15", "format"=>"Image", "subject"=>"Yet another image test.", "copy"=>"What about it this time?", "short_copy"=>""}, "facebook"=>"1", "commit"=>"Update Post", "id"=>"2"}
  Post Load (0.1ms)  SELECT  "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1  [["id", 2]]
   (0.1ms)  begin transaction
   (0.1ms)  commit transaction
Redirected to http://localhost:3000/calendars/3
Completed 302 Found in 7ms (ActiveRecord: 0.3ms)

从那里,我会说 "facebook"=&gt;"1" 并且帖子已保存,但是当我在终端中转到 rails console 时,我仍然得到 "facebook"=&gt;nil

————

更新 2:这是新的服务器日志,当我使用 &lt;%= check_box_tag(["post"]["facebook"]) %&gt; 时:

Started PATCH "/posts/2" for ::1 at 2015-10-16 11:24:07 -0700
Processing by PostsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"ByX04ciySTvKglgJGdTGsXSIOou443o02FfPJqNSn6BC3P980xKE+5fNoJKgPMG1y8xXIzm2JsDuSvFW8hs1Fg==", "post"=>{"date(1i)"=>"2015", "date(2i)"=>"9", "date(3i)"=>"22", "time(1i)"=>"2000", "time(2i)"=>"1", "time(3i)"=>"1", "time(4i)"=>"08", "time(5i)"=>"15", "format"=>"Image", "subject"=>"Yet another image test.", "copy"=>"What about it this time?", "short_copy"=>""}, "facebook"=>"1", "commit"=>"Update Post", "id"=>"2"}
  Post Load (0.1ms)  SELECT  "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1  [["id", 2]]
   (0.1ms)  begin transaction
   (0.1ms)  commit transaction
Redirected to http://localhost:3000/calendars/3
Completed 302 Found in 5ms (ActiveRecord: 0.3ms)

————

更新 3:当我使用 &lt;%= check_box_tag("post[facebook]") %&gt; 时,这里(再次)是一些新的服务器日志:

Started PATCH "/posts/2" for ::1 at 2015-10-16 11:31:25 -0700
Processing by PostsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"vOBGP+yXhCd9GpIbOx6+UqZCptsQcBKvfX5MM2sgvHz5GU2i9zdJ5yBVaoCC9rlWGQbLc5ElTltLY3JDOmkWyg==", "post"=>{"date(1i)"=>"2015", "date(2i)"=>"9", "date(3i)"=>"22", "time(1i)"=>"2000", "time(2i)"=>"1", "time(3i)"=>"1", "time(4i)"=>"08", "time(5i)"=>"15", "format"=>"Image", "subject"=>"Yet another image test.", "copy"=>"What about it this time?", "short_copy"=>""}, "facebook"=>"1", "commit"=>"Update Post", "id"=>"2"}
  Post Load (0.2ms)  SELECT  "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1  [["id", 2]]
   (0.2ms)  begin transaction
   (0.1ms)  commit transaction
Redirected to http://localhost:3000/calendars/3
Completed 302 Found in 6ms (ActiveRecord: 0.5ms)

————

UPDATE 4:还有一些服务器日志,当我使用&lt;%= f.checkbox :facebook %&gt;时:

Started PATCH "/posts/2" for ::1 at 2015-10-16 11:35:32 -0700
Processing by PostsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"kl0vM/bXVM+0m9z4JD4g/HcVA5YY4NYOfGnd/YP7kjjXpCSu7XeZD+nUJGOd1if4yFFuPpm1ivpKdOON0rI4jg==", "post"=>{"date(1i)"=>"2015", "date(2i)"=>"9", "date(3i)"=>"22", "time(1i)"=>"2000", "time(2i)"=>"1", "time(3i)"=>"1", "time(4i)"=>"08", "time(5i)"=>"15", "format"=>"Image", "subject"=>"Yet another image test.", "copy"=>"What about it this time?", "short_copy"=>""}, "facebook"=>"1", "commit"=>"Update Post", "id"=>"2"}
  Post Load (0.2ms)  SELECT  "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1  [["id", 2]]
   (0.2ms)  begin transaction
   (0.1ms)  commit transaction
Redirected to http://localhost:3000/calendars/3
Completed 302 Found in 9ms (ActiveRecord: 0.4ms)

————

我怎样才能得到以下行为:

  • post.facebook 的默认值 => false
  • :facebook 复选框的默认状态 => unchecked
  • 选中:facebook 复选框时post.facebook 的值=> true
  • 选中:facebook 复选框时:facebook 复选框的状态 => checked

我发现了以下 Stack Overflow 问题,但无法从那里找到解决问题的方法:

这似乎是一个基本要求/问题,我相信我遵循了 Rails 文档,但我无法弄清楚。

知道我错过了什么/做错了吗?

【问题讨论】:

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


    【解决方案1】:

    您的 facebook 属性不在 post 参数内。

    你必须做出的改变:

    <%= form_for [@calendar, @post], html: { multipart: true } do |f| %>
    

    <%= f.check_box :facebook, checked: true %>
    

    【讨论】:

    • 谢谢,这是一个错字(在我的代码中,不仅在问题中)。我修复了它,但仍然遇到同样的问题。
    • 我更新了我的答案。您确定帖子已保存吗?
    • 谢谢。我更新了问题以回答您的评论;)我相信帖子已保存,是的。
    • 从您的服务器日志中我可以看到,facebook 不在 post 参数哈希中。它在外面。我更新了我的答案。
    • 我没有看到:这是什么意思,我该如何解决?
    【解决方案2】:

    看起来您应该从 @crispychicken 获得所需的信息,但是由于您似乎在努力使其正常工作,因此您需要执行以下操作:

    #app/controllers/posts_controller.rb
    class PostsController < ApplicationController
       def new
           @calendar = Calendar.find params[:calendar_id]
           @post = @calendar.posts.new
       end
    
       def create
           @calendar = Calendar.find params[:calendar_id]
           @post = @calendar.posts.new post_params
           @post.save
       end
    
       private
    
       def post_params
          params.require(:post).permit(:date, :time, :subject, :format, :copy, :image, :short_copy, :score, :facebook, :twitter, :instagram, :pinterest, :google, :linkedin, :tumblr, :snapchat, :approval)
       end
    end
    

    这将允许您在表单中使用以下内容:

    #app/views/posts/new.html.erb
    <%= form_for [@calendar, @post] do |f| %>
        <%= f.check_box :facebook %>
    <% end %>
    

    这与您的其他代码一起应该能够创建一个新的post 并插入facebook 值。


    一些关于你的代码的指针:

    --

    循环

    始终使用循环或partials 来删除低效的代码。

    另外,不要使用 HTML 来样式化您的应用。当您可以在其中一个 div 上轻松使用 border-top 时,您正在使用 &lt;hr&gt;&lt;hr&gt; 应该用于在您的实际内容中真正提供水平规则,作为风格化元素。

    #app/views/shared/_errors.html.erb
    <%= content_tag :div, class: error_explanation do %>
       <%= content_tag :h2, "#{pluralize(@post.errors.count, "error")} prohibited this post from being saved:" %>
       <%= content_tag :ul do %>
          <%= errors.full_messages.each do |message| %>
             <%= content_tag :li, message %>
          <% end %>
       <% end %>
    <% end %>
    
    #app/views/posts/new.html.erb
    <%= form_for [@calendar, @post], html: { multipart: true } do |f| %>
      <% render "errors", locals: { errors: @post.errors } if @post.errors.any? %>
    
      <%= content_tag :div, class: "field" do %>
        <%= content_tag :h3, "Post details" %>
    
        <% time = %i(date time) %>
        <% time.each do |t| %>
           <%= content_tag :p do %>
                <%= f.label :t %>
                <%= f.send("#{t}_select", t %>
           <% end %>
        <% end %>
        <%= content_tag :p do %>
          <%= f.label :format %>
          <%= f.select :format, ['Simple Status', 'Image', 'Link', 'Video'] %>
        <% end %>
    
        <%= content_tag :h3, "Post content" %>
        <% opts = [[:subject, "text_field"],[:copy, "text_area"]] %>
        <% opts.each do |type, field| %>
           <%= content_tag :p do %>
               <%= f.label type %>
               <%= f.send(field, type) %>
           <% end %>
        <% end %>
        <%= content_tag :p do %>
          <%= f.label :short_copy, "Short copy (Twitter only)" %>
          <%= f.text_area :short_copy %>
        <% end%>
    
    
        <% content_tag :h3, "Social channels" %>
        <% social = %i(facebook twitter instagram pinterest google linkedin tumblr snapchat) %>
        <% social.each do |s| %>
           <%= content_tag :p do %>
              <%= f.label_tag(s, s.to_s.titleize)%>
              <%= f.check_box_tag s %>
           <% end %>
        <% end %>
    
    
        <%= content_tag :h3, "Post Image" %>
        <%= content_tag :p do %>
          <%= f.label :image %>
          <%= f.file_field :image %>
        <% end %>
    
      <% end %>
    
      <%= f.submit %>
    <% end %>
    

    【讨论】:

    • 非常感谢,非常感谢您的帮助。
    猜你喜欢
    • 2014-08-07
    • 2012-10-19
    • 2011-01-14
    • 1970-01-01
    • 2016-05-19
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多