Rails3 with SQLite3::SQLException: no such column HABTM - ruby-on-rails-3

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

Related

Adding attribute to already existing model

I am trying to add user:references onto my already existing model. This is what I originally wrote:
rails g model Post title:string description:text
I do this to add the user:references by running rails generate migration add_user_to_posts user:references, I am receiving this error upon running rake db:migrate:
-- create_table(:users)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: table "users" already exists
I am reading the error and I understand I already have a User model, however, I want to add this attribute to the Post model, not the User model.
Db file:
Posts:
class CreatePosts < ActiveRecord::Migration[5.0]
def change
create_table :posts do |t|
t.string :title
t.text :description
t.timestamps
end
end
end
Trying to add the user to posts:
class AddUserToPosts < ActiveRecord::Migration[5.0]
def change
add_reference :posts, :user, foreign_key: true
end
end
Users:
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :name
t.string :uid
t.string :avatar_url
t.timestamps
end
add_index :users, :uid
end
end
However, rake db:migrate gives me the error above.

Heroku Production Rails(3.2.3) Active admin(0.5) Globalise 3 NoMethodError in create & update

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.......

using activeuuid gem for existing database in rails

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/

uuidtools, rspec and Rails 3

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.

How do I add columns to devise after the initial create_table rake?

I installed Devise, raked, and then realized afterwards, that I want to add :confirmable.
Can I go back to the same initial migration and just uncomment out the helper that I want and then rake db:migrate again?
I tried it and it didn't seem to work. But I haven't seen an example of how to create a follow-on migration.
Thanks!
This is what I tried:
1 class AddConfirmableToUsers < ActiveRecord::Migration
2 def self.up
3 change_table :users do |t|
4 t.confirmable
5 end
6 add_index :users, :confirmation_token, :unique => true
7 end
8
9 def self.down
10 remove_column :users, :confirmation_token
11 end
12
13 end
You can add the proper columns yourself like so:
class AddConfirmableToUsers < ActiveRecord::Migration
def self.up
change_table :users do |t|
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
end
add_index :users, :confirmation_token, :unique => true
end
def self.down
change_table :users do |t|
t.remove :confirmation_token, :confirmed_at, :confirmation_sent_at
end
remove_index :users, :confirmation_token
end
end
Your migration should work. Did you check your User model to make sure :confirmable is enabled? It's commented out by default.
If you don't mind losing your data you can just do
> rake db:drop
Otherwise you can just edit the initial migration and do a rollback.
# get the current migration version
> rake db:version
> Current version: ****************41
> rake db:rollback ****************40
Make your changes
> rake db:migrate