我对Rails非常陌生,也找不到解决这个问题的方法(我希望我没有遗漏一些显而易见的东西)。
如何使我的应用程序接受空白字段,但不将空值保存到db?
我是说,如果我知道
validates :name, presence: true我会收到一条错误信息,那个名字不能是空的。但我只想让它忽略空白/零,而不把它保存到数据库中。
我该怎么做?(我希望问这个问题是可以理解的,如果不是,请告诉我)
更新:
好的,这是我的代码:
型号:
class Voting < ApplicationRecord
has_many :options
accepts_nested_attributes_for :options
validates :content, presence: true
end和
class Option < ApplicationRecord
belongs_to :voting
validates_associated :voting
validates :vote, presence: { message: "at least two Options required." }, if: :option_counter
def option_counter
voting.options.count < 2
end
endOptionsController:
class OptionsController < ApplicationController
def index
@voting = Voting.find(params[:voting_id])
@options = @voting.options
end
def create
@voting = Voting.find(params[:voting_id])
@option = @voting.options
@option.create(option_params)
if @voting.valid?
flash[:notice] = "Voting created!"
redirect_to voting_options_path
else
render 'votings/show'
end
end
private
def option_params
...
end
end视图: votings/show.html.erb
<strong>Your Voting:</strong>
<p><%= @voting.content %></p>
<% if @voting.errors.any? %>
<div>
<% @voting.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</div>
<% end %>
<ul>
<%= form_with(model: [ @voting, @voting.options.build ], local: true) do |form| %>
<p>
<%= form.label :vote %><br>
<% 3.times do %>
<input type="string" name="option[][vote]" /><br><br>
<% end %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
</ul>我想,这应该是有趣的东西。我希望这有助于了解情况。
发布于 2018-01-24 17:04:47
保存到数据库时会发生验证。因此,即使使用验证,也可以接受空字段。但是你必须在存钱之前提供一个值。如果您收到错误,这是因为您的应用程序试图保存记录。因此,您的代码没有执行您所说的操作(接受空字段而不保存)。你在存钱。
问题是。哪一行代码会引发错误?看看你的日志。
验证在这里解释:callbacks.html (或任何其他版本)
编辑1
如果要防止此记录保存,但不通知用户,则可以定义方法save_unless_empty
def save_unless_empty
if empty_fields? and new_record?
delete
else
save
end
end您必须定义empty_fields吗?方法,以便检查所需的字段。
编辑2
谢谢你添加代码。我看到您正在OptionsController#Create中创建许多选项。这个方法应该只创建一个选项。您应该在VotingsController#create (或# update )中创建或更新许多选项,因为所有选项都属于一个表决对象。
另一个问题:您正在表单中构建一个新的选项对象( @voting.options.build ),但是您没有使用它(您应该使用fields_for : option,@voting.options.build do.)。这可能在3次循环中。更好的是,这可以在控制器中完成,然后再显示视图。
再来一次。您对至少两个选项的验证应该在投票模型中进行。
一些重构(尽管仍然缺少很多):
在视野中
<%= form_with @voting do |form| %>
<%= form.label :vote %><br>
<% @options.each do |option| %>
<%= form.fields_for option do |form_opt| %>
<%= form_opt.input_field :vote %><br><br> #question: is vote really the name of the attribute in the option model? or should this be a check_box showing the option name?
<% end %>
<% end %>
<%= form.submit %>
<% end %>然后,应该将保存逻辑放在VotingsController中:
class VotingsController < ApplicationController
def new
@voting = Voting.new
3.times do
@voting.options.build
end
@options = @voting.options
end
def edit
@voting = Voting.find_by(id: params[:id])
@options = @voting.options
end
def create
@voting = Voting.create_without_null_options(voting_params)
#etc
end
def edit
@voting = Voting.find_by(id: params[:id])
@voting.update_without_null_options(voting_params)
#etc
end
private
def voting_params
...
end
end在投票模型中
def self.create_without_null_options params
#Create the voting without its options
@voting = Voting.create(params.except[:options_attributes])
#create options but save only non empty options
params[:options_attributes].each do |option_att|
@option = @voting.options.build(option_att)
@option.save_unless_empty
end
end
def update_without_null_options params
#Save the voting without its options
update_attributes(params.except[:options_attributes])
#create options but save only non empty options
params[:options_attributes].each do |option_att|
@option = options.build(option_att)
@option.save_unless_empty
end
end发布于 2018-01-24 14:54:32
验证所做的是检查:name字段是否有一个值(如果它没有值,它将显示错误消息)。
如果您希望允许一个空白值,那么我很肯定您只需要删除该验证。如果空白值(即字符串‘')保存在数据库中,那么我将检查'name’列(在数据库中),以查看是否允许null。
发布于 2018-01-25 18:48:51
不存在保存特定数据库字段的事情。存储/接收整个记录。
如果不需要名称字段,则删除模型上的validates :name, presence: true。
如果数据库中有一个默认值,而不是nil/"",则可以在迁移中设置它;例如,一个空格
add_column :name, :string, :default => " "如果需要保存这些记录并修改该数据库列,则可以在新的迁移中使用change_column。
change_column :users, :name, :string, :default => " "我使用用户作为示例表名,因为从上面的代码中,我无法理解名称列在哪个表上。
https://stackoverflow.com/questions/48425178
复制相似问题