ActiveRecord Create ignores value - ruby-on-rails-3

I am doing this
CasPgtiou.create({:pgt_iou => "a", :pgt_id => "b"})
which results in
INSERT INTO `cas_pgtious` (`created_at`, `pgt_id`, `pgt_iou`, `updated_at`) VALUES ('2015-06-25 02:22:55', NULL, NULL, '2015-06-25 02:22:55')
Mysql2::Error: Column 'pgt_id' cannot be null: INSERT INTO `cas_pgtious` (`created_at`, `pgt_id`, `pgt_iou`, `updated_at`) VALUES ('2015-06-25 02:22:55', NULL, NULL, '2015-06-25 02:22:55')
ActiveRecord::StatementInvalid: Mysql2::Error: Column 'pgt_id' cannot be null: INSERT INTO `cas_pgtious` (`created_at`, `pgt_id`, `pgt_iou`, `updated_at`) VALUES ('2015-06-25 02:22:55', NULL, NULL, '2015-06-25 02:22:55')
Even though the value is there the create function is not taking it.
Also the model I have is like this
class CasPgtiou < ActiveRecord::Base
attr_accessible :pgt_iou, :pgt_id
end
Rails version is 3.1.3. I'm not sure why a thing as simple as this would fail.
PS I have tried create this way also. But same error
CasPgtiou.create(:pgt_iou => "a", :pgt_id => "b")
UPDATE
This thing strangely works
pgtiou = CasPgtiou.new
pgtiou[:pgt_iou] = pgt_iou
pgtiou[:pgt_id] = pgt
pgtiou.save!

Related

Laravel Violates not-null constraint with default value

I am having an issue with Laravel and default values. I created the field in my table like so:
$table->string('title', 255)->default('');
And in the model, I have a default set again using this:
protected $attributes = [
'title' => '',
];
Yet I am always getting this error:
SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column
"title" violates not-null constraint DETAIL: Failing row contains
(3dd07c7a-e3f3-4f20-8d16-0f066b219dc2, dsfs, sdfs, null, null, null,
sdfs, null, 0, 0, 0, 0, 0, 0, null, null, null). (SQL: insert into
"users" ("title", "first_name", "last_name", "email", "business_unit",
"linkedin_profile") values (, dsfs, sdfs, sdfs, , ) returning
"user_id")
My abbreviated save action (example without validation) is the following:
$data = Input::all();
$user = new Users($data);
$user->save();
The following is the $data:
array (size=12)
'_token' => string '0EI9JGmgiNDAqmv83pdQZaktyWNLiX3GB9JQSfvA' (length=40)
'first_name' => string 'ads' (length=3)
'last_name' => string 'asd' (length=3)
'email' => string 'asd' (length=3)
'title' => null
'business_unit' => null
'linkedin_profile' => null
'is_admin' => string '0' (length=1)
'is_employee' => string '0' (length=1)
'is_manager' => string '0' (length=1)
'is_trainer' => string '0' (length=1)
'rt' => string '/users' (length=6)
How come my default value is not being set?
The problem is that your database column does not allow null values for title.
You can allow them like this:
$table->string('title')->nullable()->default('');
Or even without the default to have it as NULL by default:
$table->string('title')->nullable();
Otherwise, you have to make sure your title is not null.
If you don't want to allow null values and convert it automatically to empty string, you can add a mutator like this to your model:
public function setTitleAttribute($title)
{
$this->attributes['title'] = is_null($title) ? '' : $title;
}
For more information: https://laravel.com/docs/5.6/eloquent-mutators
Because the 'title' key is in the provided array, it'll try to insert it: you should be able to insert null values.
You could use a mutator setTitleAttribute($val) method in your Model class, or simply unset the 'title' array key if the value is empty before inserting. You could also filter using collection helpers or array_filter to remove unset all null values.

NULL values in database on create action

When i clicked to submit, the parameters is shown with all the data, however, when i save it, it shows as:
SQL (1.0ms) INSERT INTO `billings` (`birth`, `city`, `country`, `created_at`, `gender`, `ictype`, `idno`, `marital`, `name`, `national`, `phone`, `postcode`, `race`, `reference_id`, `shipping_address`, `state`, `street1`, `title`, `updated_at`, `uptime`, `user_id`) VALUES (NULL, NULL, NULL, '2014-08-28 02:55:19', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, '2014-08-28 02:55:19', NULL, 1)
class Billing < ActiveRecord::Base
# attr_accessible :user_id
attr_accessible :title, :birth, :ictype, :idno, :race, :gender, :national, :street1, :postcode, :city, :state, :marital, :shipping_address
belongs_to :user
end
Class ShoppingCartsController < ApplicationController
def create
#billing = Billing.new(params[:billing])
#billing = current_user.build_billing
#billing.save
end
end
Why is it so?
The answer is:
def create
# #billing = Billing.new(params[:billing])
#billing = current_user.build_billing(params[:billing])
#billing.save
end

Error with save! method in Rails 3.1.0-rc6

Dont know what I am doing wrong...
Have this code:
new_model = Model.new(:brand_id=>brand_id, :name=>new_model_name)
new_model.save!
ModelImage.upload(new_model.id, params[:images])
but new_model.id equals to nil. WTF?
Tried in rails c, no errors. SQl is OK.
Thx.
Some code from Rails Console:
irb(main):045:0> h = Model.create(:brand_id=>2, :name=>'SKyFy')
SQL (0.1ms) BEGIN
SQL (42.2ms) INSERT INTO `models` (`brand_id`, `id`, `name`) VALUES (?, ?, ?) [["brand_id", 2], ["id", nil], ["name", "SKyFy"]]
(118.7ms) COMMIT
=> #<Model id: nil, brand_id: 2, name: "SKyFy">
irb(main):046:0> h.id
=> nil
Dont have any attr_*, validations. Models are clear.
Another example:
irb(main):048:0> h = Model.new(:brand_id=>1, :name=>'SKYDOS')
=> #<Model id: nil, brand_id: 1, name: "SKYDOS">
irb(main):049:0> h.save!
SQL (0.2ms) BEGIN
SQL (3.4ms) INSERT INTO `models` (`brand_id`, `id`, `name`) VALUES (?, ?, ?) [["brand_id", 1], ["id", nil], ["name", "SKYDOS"]]
(83.5ms) COMMIT
=> true
irb(main):050:0> h.id
=> nil
irb(main):051:0> h.errors
=> #<ActiveModel::Errors:0x9a37c18 #base=#<Model id: nil, brand_id: 1, name: "SKYDOS">, #messages={}>
irb(main):052:0>
PS
Solved my problem... had TWO primary keys.
Thx to all.
Set
config.active_record.schema_format = :sql
in config/application.rb
this should hopefully solve your problems.
Note the query,
INSERT INTO `models` (`brand_id`, `id`, `name`) VALUES (?, ?, ?) [["brand_id", 1], ["id", nil], ["name", "SKYDOS"]
This query is wrong, Rails doesn't know about the primary key of the table and assumes (incorrectly) that id is just a normal column. With an SQL schema format - this should work fine.
You can confirm this by looking at db/schema.rb and you will end up with something like:
create_table "foos", :id => false, :force => true do |t|
t.integer "id", :null => false
...
end
It's hard to say with so little information, but the answer most likely lies in your validations for new_model.
Have a look at new_model.rb and see if there are any validations that may be failing.
If not, see if you have an attr_accessible/attr_protected conflict.
To help you find the answer quickly, add the line:
logger.debug new_model.errors
after your save! and you'll see what's going on in your logs.
Make sure that you have primary key 'id' with auto_increment in model's table.

the column 'id' is not the primary_key ,how to reset the Relationship

I have a table form the second database,it is not through a migration
class Dzhfeed < Dzxdb
set_table_name "pre_home_feed"
set_primary_key :feedid
end
the table:
CREATE TABLE pre_home_feed (
feedid int(10) unsigned NOT NULL auto_increment ,
appid smallint(6) unsigned NOT NULL default '0' ,
icon varchar(30) NOT NULL default '' ',
uid mediumint(8) unsigned NOT NULL default '0' ,
username varchar(15) NOT NULL default '' ',
dateline int(10) unsigned NOT NULL default '0' ,
friend tinyint(1) NOT NULL default '0',
hash_template varchar(32) NOT NULL default '' ,
hash_data varchar(32) NOT NULL default '' ,
title_template text NOT NULL,
title_data text NOT NULL,
body_template text NOT NULL ,
body_data text NOT NULL,
body_general text NOT NULL ,
image_1 varchar(255) NOT NULL default '' ,
image_1_link varchar(255) NOT NULL default '',
image_2 varchar(255) NOT NULL default '' ,
image_2_link varchar(255) NOT NULL default '' ,
image_3 varchar(255) NOT NULL default '' ,
image_3_link varchar(255) NOT NULL default '' ,
image_4 varchar(255) NOT NULL default '' ,
image_4_link varchar(255) NOT NULL default '' ,
target_ids text NOT NULL ,
id mediumint(8) unsigned NOT NULL default '0' ,
idtype varchar(15) NOT NULL default '' ,
hot mediumint(8) unsigned NOT NULL default '0' ,
PRIMARY KEY (feedid),
KEY uid (uid,dateline),
KEY dateline (dateline),
KEY hot (hot),
KEY id (id,idtype)
) ;
but this table has another column named 'id' and not a primary_key
so ,when i want to create a new Dzhfeed ,I don't know how to set the column named id
my code is
feed = Dzhfeed.new(:appid => 0, :icon => 'doing', :uid => 1, :username => 'admin', :title_template => "xxxxxxxxxx", :body_template => '', :dateline => Time.now, :id => 0)
but it not work
the error is
Mysql::Error: Column 'id' cannot be null: INSERT INTO `pre_home_feed` (`image_3`, `uid`, `id`, `dateline`, `title_template`, `idtype`, `image_1`, `username`, `body_template`, `image_1_link`, `image_3_link`, `friend`, `title_data`, `appid`, `body_data`, `image_2_link`, `hot`, `image_4_link`, `image_4`, `hash_template`, `body_general`, `icon`, `target_ids`, `hash_data`, `image_2`) VALUES ('', 1, NULL, 1304675043, 'xxxxxxxxxx', '', '', 'admin', '', '', '', 0, '', 0, '', '', 0, '', '', '', '', 'doing', '', '', '')
How did you create the table "pre_home_feed". If it is through a migration, it would have added a id column by default and set it as a primary key. In order not to add a 'id' column you have to say :id => false, :force => true in your table definition migration file and re-run the migration. ( Re-running a migration would first require a rollback, rake db:rollback. This command will undo the last migration run. )
The way you're setting the primary key is perfectly fine. You go about creating the objects in the standard way like this;
#feed = Dzhfeed.new( :feedid => :value .. )
I suggest you go through the Rails Guides.
Update:
Linking to a two different databases is a little different. Essentially, you need to use the establish_connection method defined in ActiveRecord::Base to do that:
establish_connection(
:adapter => "postgresql",
:host => "localhost",
:username => "username",
:password => "password",
:database => "database_to_link_to"
)
Update:
According to this post here your problem should be solved using composite_primary_keys gem.
Essentially what you need to do is this:
Install the gem composite_primary_keys, and then
require 'composite_primary_keys'
class Dzhfeed < Dzxdb
set_primary_keys :feedif
end
Notice, it is set_primary_keys and not set_primary_key. This should solve your problem.

Can this query be any more DRY?

I've just checked out the ON DUPLICATE KEY UPDATE for MySQL.
Here is an example query.
$query = 'INSERT INTO `activities`
(`id`,
`hole_id`,
`name_id`,
`start_depth`,
`end_depth`,
`start_time`,
`end_time`
) VALUES (
:id,
:hole_id,
:name_id,
:start_depth,
:end_depth,
:start_time,
:end_time
) ON DUPLICATE KEY UPDATE
`id` = :id,
`hole_id` = :hole_id,
`name_id` = :name_id,
`start_depth` = :start_depth,
`end_depth` = :end_depth,
`start_time` = :start_time,
`end_time` = :end_time
';
There is a lot of repetition there obviously.
Is there a way to say "insert, or if exists use the existing information to update".
I've looked at REPLACE, and it says it inserts and deletes if neccessary. The docs say to insert or update to use the method I've used above.
So can I eliminate doubling up of all that update info?
You can use the VALUES() function to refer to the value of a column rather than repeating the value in the ON DUPLICATE KEY portion. See: http://dev.mysql.com/doc/refman/5.1/en/miscellaneous-functions.html#function_values.
For example:
$query = 'INSERT INTO `activities`
(`id`,
`hole_id`,
`name_id`,
`start_depth`,
`end_depth`,
`start_time`,
`end_time`
) VALUES (
:id,
:hole_id,
:name_id,
:start_depth,
:end_depth,
:start_time,
:end_time
) ON DUPLICATE KEY UPDATE
`id` = VALUES(id),
`hole_id` = VALUES(hole_id),
`name_id` = VALUES(name_id),
`start_depth` = VALUES(start_depth),
`end_depth` = VALUES(end_depth),
`start_time` = VALUES(start_time),
`end_time` = VALUES(end_time)
';