boolean input_filed 立即调用 Rails 上的方法
boolean input_filed calls immediately the method on Rails
我正在从事的项目是在 Rails 上开发的,使用 haml 标记来查看。有一个像这样的简单形式的视图:
= simple_form_for @message, url: [:admin, @request, @message], html: { class: 'form vertical-form} do |f|
= f.input :text, as: :text, input_html: { class: 'form-control', rows: 5 }
%br
= f.input :link_url, input_html: { class: 'form-control'}
%br
- if @message.has_picture_image?
= f.label :image
=link_to @message.picture_image, target: "_blank" do
= image_tag @message.picture_image(:thumb)
= f.file_field :image, class:'imagen-button'
= f.input_field :remove_picture, as: :boolean, inline_label: 'Remove'
%br
.form-actions
= f.submit(t('accept'), class: 'btn btn-large btn-primary')
= link_to(t('cancel'), [:admin, @message.request, @message], class: 'btn btn-large btn-danger')
在消息模型中有以下方法:
def remove_picture
self.picture.destroy
end
input_field
用于检查是否要删除消息图像(如果存在)。我知道 input_filed
给了我检查它的选项,这样当我点击 accept
按钮时,它会调用 Message 模型中的方法 remove_picture。但是,在浏览器部署表单之前,它会出现下一个错误:
undefined method `to_i' for #<Picture:0x007f7675162b58>
Extracted source (around line #39):
37: = image_tag @message.picture_image(:thumb)
38: = f.file_field :image, class:'imagen-button'
39: = f.input_field :remove_picture, as: :boolean, inline_label: 'Remove'
40: %br
41: .form-actions
42: = f.submit(t('accept'), class: 'btn btn-large btn-primary')
如果我重新加载页面,这次将部署表单。我想这是因为第一次,因为图片存在,然后立即调用 remove_picture
并删除图片,当我重新加载表单时,因为图片已经不存在,所以显示了表单。
显然我对 input_field 用法的理解有误。
SimpleForms input_field
是一个将输入绑定到模型属性的助手。它不会创建一个在框被打勾时调用您的方法的框!但它会在呈现表单时调用您的 remove_picture
方法。
在某些情况下,例如复选框,您需要将输入绑定到未保存在数据库中的属性。我们称这些为虚拟属性。它们就像任何旧的 Ruby 属性:
class Message < ActiveRecord::Base
attr_accessor :remove_picture
# since this method is destructive it should have a bang (!)
def remove_picture!
self.picture.destroy
end
end
你可以这样使用它:
class MessagesController < ApplicationController
def update
@message.update(update_params)
@message.remove_picture! if message.remove_picture
# ...
end
def update_params
params.require(:message).allow(:remove_picture)
end
end
但还有更好的方法:
class Message < ActiveRecord::Base
has_one :picture_image
accepts_nested_attributes_for :picture_image, allow_destroy: true
end
accepts_nested_attributes_for
让我们使用 picture_image_attributes
创建一个图像并使用
销毁图像:
@picture.update(picture_image_attributes: { _destroy: true })
这就是我们设置表单的方式:
= simple_form_for @message, url: [:admin, @request, @message], html: { class: 'form vertical-form} do |f|
= f.input :text, as: :text, input_html: { class: 'form-control', rows: 5 }
%br
= f.input :link_url, input_html: { class: 'form-control'}
%br
- if @message.has_picture_image?
f.simple_fields_for :picture_image do |pif|
= pif.label :image
= link_to @message.picture_image, target: "_blank" do
= image_tag @message.picture_image(:thumb)
= pif.file_field :image, class:'imagen-button'
= pif.input_field :_destroy, as: :boolean, inline_label: 'Remove'
%br
.form-actions
= f.submit(t('accept'), class: 'btn btn-large btn-primary')
= link_to(t('cancel'), [:admin, @message.request, @message], class: 'btn btn-large btn-danger')
还有你的强参数白名单:
def update_attributes
params.require(:message).allow(
:text,
:link_url,
picture_image_attributes: [:image, :_destroy]
)
end
我正在从事的项目是在 Rails 上开发的,使用 haml 标记来查看。有一个像这样的简单形式的视图:
= simple_form_for @message, url: [:admin, @request, @message], html: { class: 'form vertical-form} do |f|
= f.input :text, as: :text, input_html: { class: 'form-control', rows: 5 }
%br
= f.input :link_url, input_html: { class: 'form-control'}
%br
- if @message.has_picture_image?
= f.label :image
=link_to @message.picture_image, target: "_blank" do
= image_tag @message.picture_image(:thumb)
= f.file_field :image, class:'imagen-button'
= f.input_field :remove_picture, as: :boolean, inline_label: 'Remove'
%br
.form-actions
= f.submit(t('accept'), class: 'btn btn-large btn-primary')
= link_to(t('cancel'), [:admin, @message.request, @message], class: 'btn btn-large btn-danger')
在消息模型中有以下方法:
def remove_picture
self.picture.destroy
end
input_field
用于检查是否要删除消息图像(如果存在)。我知道 input_filed
给了我检查它的选项,这样当我点击 accept
按钮时,它会调用 Message 模型中的方法 remove_picture。但是,在浏览器部署表单之前,它会出现下一个错误:
undefined method `to_i' for #<Picture:0x007f7675162b58>
Extracted source (around line #39):
37: = image_tag @message.picture_image(:thumb)
38: = f.file_field :image, class:'imagen-button'
39: = f.input_field :remove_picture, as: :boolean, inline_label: 'Remove'
40: %br
41: .form-actions
42: = f.submit(t('accept'), class: 'btn btn-large btn-primary')
如果我重新加载页面,这次将部署表单。我想这是因为第一次,因为图片存在,然后立即调用 remove_picture
并删除图片,当我重新加载表单时,因为图片已经不存在,所以显示了表单。
显然我对 input_field 用法的理解有误。
SimpleForms input_field
是一个将输入绑定到模型属性的助手。它不会创建一个在框被打勾时调用您的方法的框!但它会在呈现表单时调用您的 remove_picture
方法。
在某些情况下,例如复选框,您需要将输入绑定到未保存在数据库中的属性。我们称这些为虚拟属性。它们就像任何旧的 Ruby 属性:
class Message < ActiveRecord::Base
attr_accessor :remove_picture
# since this method is destructive it should have a bang (!)
def remove_picture!
self.picture.destroy
end
end
你可以这样使用它:
class MessagesController < ApplicationController
def update
@message.update(update_params)
@message.remove_picture! if message.remove_picture
# ...
end
def update_params
params.require(:message).allow(:remove_picture)
end
end
但还有更好的方法:
class Message < ActiveRecord::Base
has_one :picture_image
accepts_nested_attributes_for :picture_image, allow_destroy: true
end
accepts_nested_attributes_for
让我们使用 picture_image_attributes
创建一个图像并使用
@picture.update(picture_image_attributes: { _destroy: true })
这就是我们设置表单的方式:
= simple_form_for @message, url: [:admin, @request, @message], html: { class: 'form vertical-form} do |f|
= f.input :text, as: :text, input_html: { class: 'form-control', rows: 5 }
%br
= f.input :link_url, input_html: { class: 'form-control'}
%br
- if @message.has_picture_image?
f.simple_fields_for :picture_image do |pif|
= pif.label :image
= link_to @message.picture_image, target: "_blank" do
= image_tag @message.picture_image(:thumb)
= pif.file_field :image, class:'imagen-button'
= pif.input_field :_destroy, as: :boolean, inline_label: 'Remove'
%br
.form-actions
= f.submit(t('accept'), class: 'btn btn-large btn-primary')
= link_to(t('cancel'), [:admin, @message.request, @message], class: 'btn btn-large btn-danger')
还有你的强参数白名单:
def update_attributes
params.require(:message).allow(
:text,
:link_url,
picture_image_attributes: [:image, :_destroy]
)
end