如果在创建/更新时字段留空而不是NULL,则为零

时间:2016-12-26 21:50:12

标签: ruby-on-rails ruby

我有一个名为Price的模型。当用户为空白的字段创建新的/更新价格时,我希望该字段为零0而不是null

form的输入Price

<%= bootstrap_form_for(@price) do |f| %>    
    <%= f.text_field :name %>
    <%= f.text_field :description %>
    <%= f.text_field :price %>
    <%= f.label :special_Price %>
    <%= f.text_field :price_2, :hide_label => true %>

    <%= f.submit class: 'button btn btn-success' %>
    <%= link_to 'Back', prices_path, class: "button btn btn-primary" %>
<% end %>

我的create_prices.rb

class CreatePrices < ActiveRecord::Migration[5.0]
  def change
    create_table :prices do |t|
      t.string :name
      t.text :description
      t.integer :price
      t.integer :price_2

      t.timestamps
    end
  end
end

我的price_controller.rb(仅限相关代码)

  def create
    @price = Price.new(price_params)

    respond_to do |format|
      if @price.save
        format.html { redirect_to action: "index" }
        format.json { render :show, status: :created, location: @price }
        flash[:success] = "Price was successfully created!"
      else
        format.html { render :new }
        format.json { render json: @price.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @price.update(price_params)
        format.html { redirect_to action: "index" }
        format.json { render :show, status: :ok, location: @price }
        flash[:success] = "Price was successfully updated!"
      else
        format.html { render :edit }
        format.json { render json: @price.errors, status: :unprocessable_entity }
      end
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_price
      @price = Price.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def price_params
      params.require(:price).permit(:name, :description, :catogery_id, :price, :price_2)
    end

我的尝试:我尝试将:default => 0:nil => false添加到我的创建模型文件中(如stackoverflow中的一些相关帖子中所示)。我还读到change足够智能,如果字段为空,则将字段更新为0。但是,它对我不起作用,当我在创建/更新时将我的字段留空时,保存/更新后字段仍为空白(而不是显示为零)。

 class CreatePrices < ActiveRecord::Migration[5.0]
  def change
    create_table :prices do |t|
      t.string :name
      t.text :description
      t.integer :catogery_id
      t.integer :price, :default => 0, :nil => false //also tried "default: 0", does not work either
      t.integer :price_2, :default => 0, :nil => false

      t.timestamps
    end
  end
end

可能的尝试:我还想在我的控制器中使用if else语句来检查它是否是blank。但是,如果表单中有20个输入字段,那么代码太多了。有没有什么有效的方法可以做到我想要做的事情?

这是我正在做的个人项目,而不是与学校/工作相关的问题。请指导我。谢谢!

1 个答案:

答案 0 :(得分:1)

也许你搞砸了什么。

这是一个新的rails项目。

$ rails -v
Rails 5.0.0.1
$ rails new lorem
$ rails g scaffold price name:string description:text price:integer  price_special:integer

$ rake db:create
Created database 'db/development.sqlite3'
Created database 'db/test.sqlite3'
$ rake db:migrate
== 20161226222013 CreatePrices: migrating =====================================
-- create_table(:prices)
   -> 0.0064s
== 20161226222013 CreatePrices: migrated (0.0066s) ============================

$ rails c
Running via Spring preloader in process 24439
Loading development environment (Rails 5.0.1)
2.3.1 :001 > p = Price.new
 => #<Price id: nil, name: nil, description: nil, price: 0, price_special: 0, created_at: nil, updated_at: nil> 
2.3.1 :002 > p.name = 'foo'
 => "foo" 
2.3.1 :003 > p.description = 'lorem ipsum dolor sit amet'
 => "lorem ipsum dolor sit amet" 
2.3.1 :004 > p.save
   (0.2ms)  begin transaction
  SQL (2.4ms)  INSERT INTO "prices" ("name", "description", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["name", "foo"], ["description", "lorem ipsum dolor sit amet"], ["created_at", 2016-12-26 22:22:45 UTC], ["updated_at", 2016-12-26 22:22:45 UTC]]
   (91.1ms)  commit transaction
 => true 
2.3.1 :005 > p
 => #<Price id: 1, name: "foo", description: "lorem ipsum dolor sit amet", price: 0, price_special: 0, created_at: "2016-12-26 22:22:45", updated_at: "2016-12-26 22:22:45"> 
2.3.1 :006 > 

迁移文件

class CreatePrices < ActiveRecord::Migration[5.0]
  def change
    create_table :prices do |t|
      t.string :name
      t.text :description
      t.integer :price, default: 0
      t.integer :price_special, default: 0

      t.timestamps
    end
  end
end

我说这只是表明,如果你做过类似的事情,那就应该有效。

请提供更多详情。

<强>更新

http://edgeguides.rubyonrails.org/active_record_validations.html#numericality

#add validations to model    
class Price < ApplicationRecord
  validates :price, :price_special, numericality: true
end

这将提供有用的错误消息。

默认表单

enter image description here

如果我将price和special_price设置为空白并提交表单,则会生成此类消息。

enter image description here

如果你想跳过这些并希望处理控制器中的东西(这不是一个好的解决方案),

更新2

默认情况下,如果您为表设置了默认值,并且如果您创建表单&#34; rails方式&#34;,则它们采用这些默认值。

<%= f.number_field :price %>
上面的例子中的

将产生

<input value="0" name="price[price]" id="price_price" type="number">

如果您的用户将这些零更改为空白,则应尝试此操作。

2.3.1 :034 > p = Price.new
 => #<Price id: nil, name: nil, description: nil, price: 0, price_special: 0, created_at: nil, updated_at: nil> 
2.3.1 :035 > params #url params mockup
 => {:name=>"lorem", :description=>"ipsum", :price=>nil, :price_special=>nil} 
2.3.1 :036 > params.each do |k,v|
2.3.1 :037 >     p[k] = ( v.present? ? v : 1 ) #1 or any default value
2.3.1 :038?>   end
2.3.1 :043 > p
 => #<Price id: nil, name: "lorem", description: "ipsum", price: 1, price_special: 1, created_at: nil, updated_at: nil> 

还看看那些 - http://api.rubyonrails.org/classes/Object.html#method-i-blank-3F - http://api.rubyonrails.org/classes/Object.html#method-i-present-3F