“.save” only inserts null values in database

2019-02-19 21:53发布

问题:

I'm trying to make a RoR application for a Hospital so it has patients, doctors, offices, etc.

The problem I'm having is that, at the patient "Sign-up", I'm not able to save the new patient in the database. In fact, despite I've checked that the attributes are ok (It's just a name and a personal ID), once the method is excecuted, in the database only appears a new row with "<null>" instead of the actual attribute values. Here's the method:

def pat_create

  pName = params[:name].to_s
  id    = params[:pid].to_s.to_i

  pat = Patient.where(:pID => id).first
  if pat == nil
    pat = Patient.new(:name => pName, :pID =>id)
    pat.save
  end

end

Also, This is the query that it constructs:

INSERT INTO `patients` (`created_at`, `name`, `pID`, `updated_at`) VALUES ('2013-05-20 02:04:28', NULL, NULL, '2013-05-20 02:04:28')

This method is called after some other view collects the :name and :pid information in this form:

<%= form_tag('/page/pat_create') do %> 
  <%= text_field_tag :name, nil%> 
  <%= text_field_tag :pid, nil%> 
  <%= button_tag(type: "submit", class: "btn btn-success") do %> 
    Register<i class="icon-white icon-plus"></i> 
  <%end%> 
<%end%>

Needless to say, pat.errors.empty? is true, and so is pat.save.

Any idea why this happens?

Here's Patient Model:

class Patient < ActiveRecord::Base

  attr_accessible :name, :pID
  attr_accessor :name, :pID

  has_many :appointments
  validates_presence_of :name
  validates :name, :format => {:with=> /^[a-zA-Z\s\D]+$/}
  validates_presence_of :pID
  validates_numericality_of :pID
  validates_inclusion_of :pID, :in => 100000..9999999999   

end

回答1:

Remove the following line in class Patient:

attr_accessor :name, :pID

What happened was that attr_accessor replaced the two database column attributes :name and :pID (which were automatically generated) with its own, resulting in two virtual attributes, :name and :pID.

Thus, the virtual attributes were being set and validated instead of the corresponding database attributes, which resulted in no errors yet null values in the database.



回答2:

Can you show us how this method is called? Also are you sure that params[:name] and params[:pid].

You have used the column :pid and :pID, as below

pat = Patient.where(:pID => id).first
if pat == nil
  pat = Patient.new(:name => pName, :pID =>id)  # should use pat = Patient.new(:name => pName, :pid =>id)
  pat.save
end


回答3:

So in your controller your params are nil but you call .to_s and .to_s.to_i which results in an empty string "" and 0 (zero). You then save them into your database. A couple recommendations:

def pat_create

  pat = Patient.new(:name => params[:name], :pid =>params[:pid])
  pat.save

end

In addition to the uniqueness validation I would make sure your db column has a unique index on it to insure no duplicate patients.

class Patient < ActiveRecord::Base

  attr_accessible :name, :pid
  attr_accessor :name, :pid

  has_many :appointments
  validates :name, presence: true, 
                   length: { maximum: 50 }, 
                   format: {:with=> /^[a-zA-Z\s\D]+$/}
  validates :pid, presence: true,
                  numericality: { only_integer: true, 
                                  greater_than_or_equal_to: 100000, 
                                  less_than_or_equal_to: 9999999999 },
                  uniqueness: true
end

If you are getting valid values this will work and if not you will see why it is not.