I'm working with the UUIDTools gem in Rails 3 and running into some problems. It seems to work fine in practice:
> item = Item.create
=> #<Item uuid: "e9d00043-9200-4497-a55c-509c5de3dd88", created_at: "2012-01-09 01:56:49", updated_at: "2012-01-09 01:56:49">
> item.id
=> "e9d00043-9200-4497-a55c-509c5de3dd88"
But then in my specs it tells a different story:
require 'spec_helper'
describe Item do
it 'should assign an id' do
item = Item.create
puts "item id: #{item.id}"
end
end
Running this spec shows:
item id: 5
.
Finished in 2.21 seconds
1 example, 0 failures
Where's my guid? There doesn't seem to be any pattern to what id is assigned, I've run this a bunch of times and seen it go anywhere from 0 to up in the thousands.
Here is my migration:
class CreateItems < ActiveRecord::Migration
def change
create_table :items, :id => false do |t|
t.string :uuid, :null => false, :primary => true
t.timestamps
end
add_index :items, :uuid, :unique => true
end
end
My model:
require 'uuid_helper'
class Item < ActiveRecord::Base
include UUIDHelper
end
And my uuid_helper:
module UUIDHelper
def self.included(base)
base.class_eval do
set_primary_key :uuid
attr_readonly :uuid
before_create :set_uuid
private
def set_uuid
self.uuid = UUIDTools::UUID.random_create.to_s
end
end
end
end
Putting some debugger logic into set_uuid I've discovered that it's doing to_i on the uuid at some point. Any suggestions?
Update This seems to be a bug in the Rails test environment. When I run RAILS_ENV=test rails console I get the same behavior as in the specs--the guids are chopped off.
Alright, the answer was to upgrade to Rails 3.1.3 from 3.1.1.
Related
As am working on the Active Admin(0.5) with Rails 3.2.3 Using Multilingual Support using Globalise 3 .
When am running application on local under development & production environment everything works great.
But when i deployed it on to the heroku production mode it throwing me error with the same code am using over local.
When i click on create new page it giving me below error:
NoMethodError in Admin::HomeTemplatesController#new
undefined method `build_app_page' for nil:NilClass
Rails.root: /app
Application Trace | Framework Trace | Full Trace
app/admin/home_templates.rb:16:in `new'
Please find below the code
ActiveAdmin.register HomeTemplate do
menu false
config.clear_action_items!
form :partial => "form"
controller do
protect_from_forgery :except => :sort
def new
# #home_template =HomeTemplate.new
# if !!current_ability.attributes_for(:create, HomeTemplate)[:app_instance_id]
# #valid_parents = AppPage.where("app_instance_id = ? AND parent_id IS NULL", current_ability.attributes_for(:create, HomeTemplate)[:app_instance_id])
# end
#home_template.build_app_page
end
def create
# if !!current_ability.attributes_for(:create, HomeTemplate)[:app_instance_id]
# #valid_parents = AppPage.where("app_instance_id = ? AND parent_id IS NULL", current_ability.attributes_for(:create, HomeTemplate)[:app_instance_id])
# end
if #home_template.present?
#home_template.app_page.protected = false;
#home_template.app_page.hidden = false;
#home_template.app_page.app_instance = #home_template.app_instance;
create!
end
end
def update
##home_template = HomeTemplate.find(params[:id])
#valid_parents = AppPage.where("app_instance_id = ? AND parent_id IS NULL", #home_template.app_page.app_instance_id)
update!
end
def edit
# if !!current_ability.attributes_for(:edit, HomeTemplate)[:app_instance_id]
# #valid_parents = AppPage.where("app_instance_id = ? AND parent_id IS NULL", current_ability.attributes_for(:edit, HomeTemplate)[:app_instance_id])
# Rails.logger.info( #valid_parents)
# Rails.logger.info( current_ability.attributes_for(:edit, HomeTemplate)[:app_instance_id])
# end
Rails.logger.info( "Home template outside")
##home_template = HomeTemplate.find(params[:id])
#valid_parents = AppPage.where("app_instance_id = ? AND parent_id IS NULL", #home_template.app_page.app_instance_id)
Rails.logger.info(#valid_parents)
end
end
collection_action :sort, :method => :post do
if(params[:ids])
params[:ids].each_with_index do |id, index|
app_page = AppPage.find(id)
app_page.move_to_child_of app_page.parent_id if can? :update, app_page.templatable
end
end
head 200
end
end
I tried to connect with console through heroku & it fetching the models.
I also checked the postgres database over local in production ode & all worked like a charm.
Right now am using Sqlite & postgres over local & heroku as postgres.
Your Help & guidance will be highly appreciable & deserves a hat off from my side.
Please let me know if any more details required.
Right now am using Polymorphic Association
as below
class HomeTemplate < ActiveRecord::Base
include BelongsToAppInstance
has_one :app_page, :as => :templatable
has_many :home_banner_images, :dependent => :destroy
accepts_nested_attributes_for :home_banner_images, :allow_destroy => true
accepts_nested_attributes_for :app_page
validates_presence_of :app_page
end
AppPages as:
class AppPage < ActiveRecord::Base
include BelongsToAppInstance
belongs_to :last_modified_by, :class_name => "AdminUser"
validates_presence_of :last_modified_by
belongs_to :templatable, :polymorphic => true, :dependent => :destroy
has_many :app_page_callouts
acts_as_nested_set
attr_readonly :hidden
attr_readonly :protected
default_scope :order => 'lft ASC'
validates_presence_of :name
#validates_uniqueness_of :name, :scope => :app_instance_id
validates_uniqueness_of :app_page_role, :scope => :app_instance_id
mount_uploader :related_pdf, PdfUploader
validate :parent_must_belong_to_same_app_instance
#validates_inclusion_of :linked_model, :in => AppPage.allowable_linked_models, :unless => Proc.new {|app_page| app_page.linked_model.blank? }
attr_accessible :name,:subtitle,:body,:app_page_attributes,
:app_instance_id,:app_page_role,:related_pdf,
:parent_id,:translations_attributes,
:last_modified_by,:app_instance,:sort,:view_controller,:hidden,:protected,:app_page_callouts,:parent
active_admin_translates :name,:subtitle,:body
#validates_globalized_uniqueness_of :name,:scope => :locale
def parent_must_belong_to_same_app_instance
if !self.parent_id.nil? && self.parent.app_instance_id != self.app_instance_id
errors.add(:parent_id, "The parent must belong to the same app instance.")
end
end
def set_view_controller
if self.view_controller.nil?
self.view_controller = "detail"
end
end
end
Actually am using active admin & in this we don't define #home_tamplate anywhere but in local or dev phase its working fine but when i uploaded it to heroku its start throwing error. Sometime when i restart the heroku it worked but other controller stop working.Its occurring very randomly over heroku with all controllers. I introduced the new & update statement & when i on this it worked for new but when i submit to create it again i get the home_template nil.......
I have a model called Issue that has the following database structure :
class CreateIssues < ActiveRecord::Migration
def change
create_table :issues do |t|
t.string :path, null: false
t.string :filename, null: false
t.string :name, null: false
t.string :year
t.integer :number
t.timestamps null: false
end
end
end
In my model tests, I use the following line :
issue = Issue.create path: "test_path", filename: "test_filename", name: "test_name"
... which raises an exception when saving :
SQLite3::ConstraintException: NOT NULL constraint failed:
issues.path: INSERT INTO "issues" ("created_at", "updated_at") VALUES (?, ?)
From what I understand, when calling create or new/save, rails starts by inserting an entry with only the timestamps. I would expect the insert to contain all of the values that I have passed to the create method. Am I missing a step in the creation process?
EDIT :
Basic information and steps:
Using SQLite3
Using Rails 4.2.1
Using RSpec
Generated the Issue model using be rails generate model Issue
Added the NULL constraints afterwords by hand
Did be rake db:migrate successfully
Tried my code in various model spec files
Tried other models, I get generated SQL that only includes the timestamps.
EDIT 2:
Here is my Issue model :
class Issue < ActiveRecord::Base
has_one :pending_issue
has_one :watched_issue
has_many :unmatched_issues
validates :path, presence: true
validates :filename, presence: true
validates :name, presence: true
attr_accessor :path
attr_accessor :filename
attr_accessor :name
attr_accessor :year
attr_accessor :number
end
Your result is anomalous. This is what I get:
# migration
class CreateIssues < ActiveRecord::Migration
def change
create_table :issues do |t|
t.string :path, null: false
t.timestamps null: false
end
end
end
Then in the console:
Issue.create path: "path"
# (0.1ms) begin transaction
# SQL (0.3ms) INSERT INTO "issues" ("path", "created_at", "updated_at") VALUES (?, ?, ?) [["path", "path"], ["created_at", "2015-06-21 16:55:08.304653"], ["updated_at", "2015-06-21 16:55:08.304653"]]
# (0.8ms) commit transaction
# => #<Issue id: 1, path: "path", created_at: "2015-06-21 16:55:08", updated_at: "2015-06-21 16:55:08">
My test:
require "test_helper"
describe Issue do
it "can be created" do
Issue.create path: "test_path"
end
end
passes. No exception.
What I think may have happened is that your database schema has become out of date on your test database.
Firstly, does a similar 'create' work in the development (default) rails console? If so, it's a big indication that something is very different in your test and development environments.
What happens if you force the console to use the test environment?
RAILS_ENV=test rails c
Does it work here?
I think you may need to manually rollback your test database to the migration which first created your issues table, then re-migrate
RAILS_ENV=test rake db:rollback
Keep applying until you reach the appropriate migration, then:
RAILS_ENV=test rake db:migrate
Does that help?
EDIT:
This appears to be the issue:
attr_accessor :path
attr_accessor :filename
attr_accessor :name
attr_accessor :year
attr_accessor :number
These will overwrite the Rails default accessors, at a guess. They are certainly not needed.
Did you accidentally omit attr_accessible for :path?
I need to implement activeuuid gem to have UUIDs instead of default Rails ids. we can implement it for creating new migration as:
class CreateStudents < ActiveRecord::Migration
def change
create_table :students, :id => false do |t|
t.uuid :id, :primary_key => true
t.string :name
t.string :email
t.timestamps
end
end
end
And in model we include ActiveUUID::UUID as:
class Student < ActiveRecord::Base
attr_accessible :email, :name
include ActiveUUID::UUID
end
Now I already have a database so how can I implement the activeuuid gem to have UUIDs instead of default Rails ids for existing DB?
Need to make changes in all migrations or what?
Need help in this regard. thanks
The UUID is stored as a binary field w/ 16 positions as I found here: https://github.com/jashmenn/activeuuid/blob/master/lib/activeuuid/patches.rb#L62
It worked for me (existing table without records):
def change
reversible do |dir|
change_table :payments do |t|
dir.up { t.change :id, :binary, limit: 16, :primary_key => true }
dir.down { t.change :id, :integer }
end
end
end
Don't forget to add those lines to your model as well:
include ActiveUUID::UUID
natural_key :at_least_one_field_here
More info in the github repo: https://github.com/jashmenn/activeuuid/
In a stripped down project to demonstrate the problem
rake test yields:
1) Failure:
test_can_mass_assign_accessible_flds(BrandTest) [ test/unit/brand_test.rb:11]:
Exception raised:
<#<ActiveModel::MassAssignmentSecurity::Error: \
Can't mass-assign protected attributes: brand_name, support_num>>.
2 tests, 2 assertions, 1 failures, 0 errors, 0 skips
The two models and tests have parallel construction but yield different results when tested. Experience tells me this should be my error but I cannot see where. Can anyone help?
Models:
class Brand < ActiveRecord::Base
attr_accessible :brand_name, :support_num, :comment
end
class Mask < ActiveRecord::Base
attr_accessible :brand_id, :brand_sku, :comment
end
Tests:
require 'test_helper'
class BrandTest < ActiveSupport::TestCase
def setup
#accessible_flds = { :brand_name => 'MyString',
:support_num => 'MyString',
:comment => 'MyText' }
end
test "can mass assign accessible flds" do
assert_nothing_raised { Mask.new(#accessible_flds) }
end
end
class MaskTest < ActiveSupport::TestCase
def setup
#accessible_flds = { :brand_id => 1,
:brand_sku => 'MyString',
:comment => 'MyText' }
end
test "can mass assign accessible flds" do
assert_nothing_raised { Mask.new(#accessible_flds) }
end
end
Schema:
ActiveRecord::Schema.define(:version => 20121212024505) do
create_table "brands", :force => true do |t|
t.string "brand_name"
t.string "support_num"
t.text "comment"
end
create_table "masks", :force => true do |t|
t.integer "brand_id"
t.string "brand_sku"
t.text "comment"
end
end
Environment:
Windows 7 Pro, SP 1
ruby -v =>> ruby 1.9.3p327 (2012-11-10) [i386-mingw32]
rails -v =>> Rails 3.2.9
Your BrandTest class is still referencing Mask:
Mask.new(#accessible_flds)
should be
Brand.new(#accessible_flds)
Using Sqlite3 with Rails3 and I receive "ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column" with a has_and_belongs_to_many situation. From rails console connected to Sqlite3, errors when page.editors or page.admin_users
[[[EDIT: Solved because of typos in the join table id's]]]
gems installed
rails 3.0.9
sqlite3 1.3.3 x86-mingw32
sqlite3-ruby
(win7 64bit dev machine)
page.rb --> OK
> class Page
> belongs_to :subject
> has_many :sections
> has_and_belongs_to_many :editors, :class_name => "AdminUser"
> #has_and_belongs_to_many :admin_users
>
> end
admin_users.rb --> OK
> class AdminUser
> has_and_belongs_to_many :pages
> scope :named, lambda {|first,last| where(:first_name =>
> first, :last_name => last)}
>
> end
migration file --> Spot the Typos!
class CreateAdminUsersPagesJoin false do |t|
t.integer :admin_users_id, :foreign_key => true # Should be admin_user_id
t.integer :page_id, :foreign_key => true
end
add_index :admin_users_pages, [:admin_users_id, :page_id] # Again admin_user_id
end
def self.down
drop_table :admin_users_pages
end
end
rails console errors
irb(main):004:0> page.admin_users
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: admin_users_pages.admin_user_id: SELECT * FROM "admin_users
" INNER JOIN "admin_users_pages" ON "admin_users".id = "admin_users_pages".admin_user_id WHERE ("admin_users_pages".page_id = 2 )
Thanks to Heikki for the posts. I fixed it myself before looking back here only now (d'oh) but I'll happily accept the answer. Post it and I'll check it since that was correct. Cheers.
By convention the foreign keys in the join table should be singular ie. admin_user_id instead of admin_users_id.
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_and_belongs_to_many
http://guides.rubyonrails.org/association_basics.html#the-has_and_belongs_to_many-association