首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails 5.1.4验证:如何接受空白属性而不将它们保存到db?

Rails 5.1.4验证:如何接受空白属性而不将它们保存到db?
EN

Stack Overflow用户
提问于 2018-01-24 14:44:25
回答 3查看 1.7K关注 0票数 0

我对Rails非常陌生,也找不到解决这个问题的方法(我希望我没有遗漏一些显而易见的东西)。

如何使我的应用程序接受空白字段,但不将空值保存到db?

我是说,如果我知道

代码语言:javascript
复制
validates :name, presence: true

我会收到一条错误信息,那个名字不能是空的。但我只想让它忽略空白/零,而不把它保存到数据库中。

我该怎么做?(我希望问这个问题是可以理解的,如果不是,请告诉我)

更新:

好的,这是我的代码:

型号:

代码语言:javascript
复制
class Voting < ApplicationRecord
  has_many :options
  accepts_nested_attributes_for :options
  validates :content, presence: true    
end

代码语言:javascript
复制
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    
end

OptionsController:

代码语言:javascript
复制
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

代码语言:javascript
复制
<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>

我想,这应该是有趣的东西。我希望这有助于了解情况。

EN

回答 3

Stack Overflow用户

发布于 2018-01-24 17:04:47

保存到数据库时会发生验证。因此,即使使用验证,也可以接受空字段。但是你必须在存钱之前提供一个值。如果您收到错误,这是因为您的应用程序试图保存记录。因此,您的代码没有执行您所说的操作(接受空字段而不保存)。你在存钱。

问题是。哪一行代码会引发错误?看看你的日志。

验证在这里解释:callbacks.html (或任何其他版本)

编辑1

如果要防止此记录保存,但不通知用户,则可以定义方法save_unless_empty

代码语言:javascript
复制
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次循环中。更好的是,这可以在控制器中完成,然后再显示视图。

再来一次。您对至少两个选项的验证应该在投票模型中进行。

一些重构(尽管仍然缺少很多):

在视野中

代码语言:javascript
复制
<%= 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中:

代码语言:javascript
复制
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

在投票模型中

代码语言:javascript
复制
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
票数 1
EN

Stack Overflow用户

发布于 2018-01-24 14:54:32

验证所做的是检查:name字段是否有一个值(如果它没有值,它将显示错误消息)。

如果您希望允许一个空白值,那么我很肯定您只需要删除该验证。如果空白值(即字符串‘')保存在数据库中,那么我将检查'name’列(在数据库中),以查看是否允许null。

票数 0
EN

Stack Overflow用户

发布于 2018-01-25 18:48:51

不存在保存特定数据库字段的事情。存储/接收整个记录。

如果不需要名称字段,则删除模型上的validates :name, presence: true

如果数据库中有一个默认值,而不是nil/"",则可以在迁移中设置它;例如,一个空格

代码语言:javascript
复制
add_column :name, :string, :default => " "

如果需要保存这些记录并修改该数据库列,则可以在新的迁移中使用change_column

代码语言:javascript
复制
change_column :users, :name, :string, :default => " "

我使用用户作为示例表名,因为从上面的代码中,我无法理解名称列在哪个表上。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48425178

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档