【问题标题】:Set a value on form submit if checkbox is checked in Rails?如果在Rails中选中复选框,则在表单提交上设置一个值?
【发布时间】:2014-02-13 00:44:14
【问题描述】:

我有一个创建帖子的表单。帖子有一个名为 school_id 的非必填字段。在帖子表单(创建新帖子)上,我有一个复选框。如果选中该复选框,我想将 :school_id 设置为等于也设置为 current_user 的 school_id (由设计创建的对象)。如果选中该复选框,如何将 Post.school_id 设置为等于 current_user.school_id?

我在表单上的复选框传递 :school_id 为 1 并且永远不会更改。这是因为复选框只能接受 1 或 0 的布尔值吗?到目前为止,这是我在表格上的内容:

<%= simple_form_for @post do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
    <%= f.text_area :content, required: true %>

  <% if @school %>
     <%= f.label :school_id, "Set school",:class => "checkbox inline"  %>
     <%= f.check_box :school_id, :value => current_user.school.id %>
  <% end %>

<%= f.submit "Submit Post", class: 'btn btn-primary' %>
<% end %>

编辑

后控制器

def create
  @school = current_user.school
  @post = current_user.posts.build(params[:post])
  @post.school_id = current_user.school_id if @school && @post.use_school.present?     
  end

带有帖子表单的控制器

def index
    @post = current_user.posts.build  
    @school = current_user.school
    @post.school_id = current_user.school_id if @school && @post.use_school.present?
     respond_to do |format|
      format.html # index.html.erb
      format.json
      format.js 
    end
    end

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 forms


    【解决方案1】:

    您的问题来自 Simpleform! Simpleform 强制复选框输入为布尔值。其他语法也会有同样的问题:

    <%= f.input :school_id, :as => :boolean, :input_html => { :value => current_user.school.id } %>
    

    更深入:

    <%= f.check_box :school_id, :value => current_user.school.id %>
    

    会生成这样的东西:

    <input type="hidden" name="post[school_id]" value="0">
    <input type="checkbox" name="post[school_id]" value="1">
    

    注意:Simpleform 会自动添加第一行(一个很好的做法),以确保在未选中输入时在提交时发送值 (0)。否则,您可能会遇到模型更新问题。

    您的字段不是布尔值,您不应该使用复选框。此外,用户可以编辑复选框(firebug & co)的值,这可能会导致数据不一致或被黑客入侵。因此,您应该使用复选框检查控制器中的 school_id 是否正确。

    我建议这个解决方法:

    app/views/posts/new.rb:

    <% if @school %>
        <%= f.label :use_school, "Set school",:class => "checkbox inline"  %>
        <%= f.input :use_school, :as => :boolean %>
    <% end %>
    

    app/models/post.rb:

    attr_accessor :use_school
    

    app/controllers/posts_controller.rb:

    @post = Post.new(params[:post])
    @post.school_id = current_user.school_id if @school && @post.use_school.present?
    

    注意:控制器部分可以直接在您的模型中使用:before_save 完成。

    【讨论】:

    • 这非常有效!非常感谢您的详细回复。这是使用 attr_accessor 方法的巧妙技巧。我真的需要仔细阅读。
    • hmm...当我创建新帖子时,无论是否选中复选框,它似乎总是将布尔值设置为 true。关于造成这种情况的任何想法?
    • Doh... 检查您的 Rails 日志中收到的值。
    • 也许可以在以下条件下尝试:!@post.use_school.to_i.zero?
    • 好的! :use_school 没有任何类型:它可能是字符串、布尔值……
    猜你喜欢
    • 2016-06-22
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 2015-11-21
    • 2017-08-18
    • 1970-01-01
    • 2013-08-30
    • 2015-04-13
    相关资源
    最近更新 更多