ActiveRecord::UnknownAttributeError: unknown attribute: p_id - ruby-on-rails

after I run
bundle exec rake db:seed
The titled error will show.
Could anyone has a look at my RoR code? I've not sure where is the issue.
my
product.rb
file
class Product < ActiveRecord::Base
set_primary_key :p_id
attr_accessible :p_id, :name, :category, :description, :price
end
schema.rb
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20111119180638) do
create_table "products", :force => true do |t|
t.string "p_id"
t.string "name"
t.string "category"
t.text "description"
t.string "price"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
end
create_products.rb
class CreateProducts < ActiveRecord::Migration
def up
create_table :products, {:id => false} do |t|
t.string :p_id
t.string :name
t.string :category
t.text :description
t.string :price
# Add fields that let Rails automatically keep track
# of when products are added or modified:
t.timestamps
end
execute "ALTER TABLE products ADD PRIMARY KEY (p_id);"
end
def down
drop_table :products
end
end

primery_key method is expecting an string:
self.primary_key 'p_id'
http://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/PrimaryKey/ClassMethods.html#method-i-primary_key-3D

Related

How to make Ahoy gem tracking visits for users with uuid?

I have a User model with uuid for id column.
Ahoy gem creates visits as expected but the user_id is wrong.
Any ideas?
ok. Got that. Ahoy gem doesn't work with user_id as UUID. It takes the first digits from uuid and stores that in user_id for Ahoy::Visit which could look like random value.
The solution is to change the user_id type to uuid.
This migration would do the trick:
class ChangeAhoyVisits < ActiveRecord::Migration[5.2]
def change
Ahoy::Visit.destroy_all
remove_column :ahoy_visits, :user_id, :bigint
add_column :ahoy_visits, :user_id, :uuid, foreign_key: true, null: true
add_index :ahoy_visits, :user_id
end
end
Probably need to add the same type: :uuid to the user_id column in the ahoy_events table as well. After a few rake db:rollback's I ended up modifying the original migration file that is created by rails generate ahoy:install to look like this before I ran the migration:
def change
create_table :ahoy_visits do |t|
t.string :visit_token
t.string :visitor_token
# the rest are recommended but optional
# simply remove any you don't want
# user
t.references :user, type: :uuid, foreign_key: true, index: true
# standard
t.string :ip
t.text :user_agent
t.text :referrer
t.string :referring_domain
t.text :landing_page
# technology
t.string :browser
t.string :os
t.string :device_type
# location
t.string :country
t.string :region
t.string :city
t.float :latitude
t.float :longitude
# utm parameters
t.string :utm_source
t.string :utm_medium
t.string :utm_term
t.string :utm_content
t.string :utm_campaign
# native apps
t.string :app_version
t.string :os_version
t.string :platform
t.datetime :started_at
end
add_index :ahoy_visits, :visit_token, unique: true
create_table :ahoy_events do |t|
t.references :visit
t.references :user, type: :uuid, foreign_key: true, index: true
t.string :name
t.jsonb :properties
t.datetime :time
end
add_index :ahoy_events, [:name, :time]
add_index :ahoy_events, :properties, using: :gin, opclass: :jsonb_path_ops
end
And after running this slightly modified migration rather than original everything seemed to populate properly on an 'ahoy.track' in the db.

Rails access and save foreign key value inside model

I have two models, Job and Survey. I am using the PaperTrail gem to track changes that occur on the models, and I want to save the job_id onto the version every time it’s created.
# app/models/job.rb
class Job < ActiveRecord::Base
has_paper_trail :ignore => [:id, :created_at, :updated_at],
:meta => { :resource_id => self.id }
has_one :survey
end
# app/models/survey.rb
class Survey < ActiveRecord::Base
has_paper_trail :ignore => [:id, :created_at, :updated_at],
:meta => { :resource_id => self.job_id }
belongs_to :job
end
# app/db/schema.db
# versions
create_table "versions", force: :cascade do |t|
t.string "item_type", null: false
t.integer "item_id", null: false
t.string "event", null: false
t.string "whodunnit"
t.text "object"
t.datetime "created_at"
t.text "object_changes"
t.integer "resource_id"
end
# surveys
create_table "surveys", force: :cascade do |t|
t.string "survey"
t.integer "job_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
When I run this code and try to save a new record, I get the following error:
undefined method `job_id' for #<Class:0x007fd53d70c0a0>
How do I correctly fetch the foreign job_id key from inside my Survey model?
Solved by using :job_id instead of self.job_id.

Why is rails not finding my table relation?

class Product < ActiveRecord::Base
has_many :models, :dependent => :destroy, :order => 'display, title'
class Model < ActiveRecord::Base
belongs_to :product
class GsCollector < ActiveRecord::Base
belongs_to :model
Why can't I do the following in my form for GsCollector?:
<p>
Model:<br />
<%= collection_select :gs_collector, :model_id, Product.where("title = 'Some Title'").models.all, :id, :title %>
</p>
I get the error:
undefined method `models' for #<ActiveRecord::Relation:0x007fef0ac09350>
Shouldn't the models method be provided by the relation? In the console, this works:
p = Product.find(4).models
But this doesn't:
p = Product.where("title = 'some title'").models
Not sure what the difference is....
Here's my schema:
create_table "gs_collectors", :force => true do |t|
t.integer "project_id"
t.integer "model_id"
t.integer "quantity", :default => 1
t.string "housing", :default => "Base Unit"
t.string "hopper"
t.string "controller"
t.boolean "overbags", :default => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "models", :force => true do |t|
t.string "title"
t.integer "product_id"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "display"
end
create_table "products", :force => true do |t|
t.string "title"
t.datetime "created_at"
t.datetime "updated_at"
end
You are returning an array of objects, collectively called a ActiveRecord::Relation. This is due to your where search term. Maybe you want something like the following:
p = Product.find_by_title('some title').models
where returns a list of Products
find returns a single Product
You need to define the relationship between Model and GsCollector both ways. You forgot the part in the Model:
class Model < ActiveRecord::Base
belongs_to :product
has_many :gs_collectors
end
class GsCollector < ActiveRecord::Base
belongs_to :model
end
And the real problem is that you can .models only on a single record. Product.where returns several ones - so use Product.find_by_title("title").models

How to set primary key in ruby on rails migration?

How can I set primary key for my IdClient field? I have tried all methods, but I'll get errors (rails 3.0.9)... Could you help me?
class CreateCustomers < ActiveRecord::Migration
def self.up
create_table :customers do |t|
t.integer :IdCustomer
t.string :username
t.string :crypted_password
t.string :password_salt
t.string :persistence_token
t.string :email
t.string :Skype
t.string :ICQ
t.string :Firstname
t.string :Lastname
t.string :Country
t.string :State
t.string :City
t.string :Street
t.string :Building
t.integer :Room
t.string :AddressNote
t.date :DateOfReg
t.integer :CustGroup
t.float :TotalBuy
t.timestamps
add_index(:customers, :IdCustomer, :unique => true)
end
end
def self.down
drop_table :customers
end
end
Also how to set relations in model?
Don't do this. Use the built-in id field as the primary key. If you're going to use Rails, you should build your app the "Rails way" unless you have very good reason not to.
If you really want to do this, you can pass a :primary_key option to create_table:
create_table :customers, :primary_key => :idClient do |t|
# ...
end
You'll also need to tell your model the name of its primary key via self.primary_key = "idClient"

rails 3.2 migration cannot add index to create_table in change method

here is my migration in rails 3.2.2:
class CreateStatistics < ActiveRecord::Migration
def change
create_table :statistics do |t|
t.string :name
t.integer :item_id
t.integer :value
t.text :desc
t.timestamps
t.index [:name, :item_id]
end
end
end
and here is the migrate error:
== CreateStatistics: migrating ===============================================
-- create_table(:statistics)
ActiveRecord::ConnectionAdapters::TableDefinition
rake aborted!
An error has occurred, all later migrations canceled:
undefined method `index' for #<ActiveRecord::ConnectionAdapters::TableDefinition:0xbd16888>
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
what is the right way to create a index?
You can still add an index as a part of a "change" migration. You just have to do it outside of the call to create_table:
class CreateStatistics < ActiveRecord::Migration
def change
create_table :statistics do |t|
t.string :name
t.integer :item_id
t.integer :value
t.text :desc
t.timestamps
end
add_index :statistics, [:name, :item_id]
end
end
This correctly creates the table and then the index on an "up" migration and drops the index and then the table on a "down" migration.
so I change it to the old way, and it works.
and I think there is a new way doing this by using change method.
class CreateStatistics < ActiveRecord::Migration
def up
create_table :statistics do |t|
t.string :name
t.integer :item_id
t.integer :value
t.text :desc
t.timestamps
end
add_index :statistics, [:name, :item_id]
end
def down
drop_table :statistics
end
end
If you have more than one index and don't want to repeat the table name several times in individual add_index calls, you can use a change_table block that follows the create_table.
create_table :user_states do |t|
t.references :user, :null => false
t.integer :rank
t.integer :status_code
end
change_table :user_states do |t|
t.index [:rank, :status_code]
end
class CreateTempPfp < ActiveRecord::Migration
def change
create_table :temp_ptps do |t|
t.string :owner
t.integer :source_id
t.string :source_type
t.integer :year
t.string :pcb_type
t.float :january
t.float :february
t.float :march
t.float :april
t.float :may
t.float :june
t.float :july
t.float :august
t.float :september
t.float :october
t.float :november
t.float :december
t.float :dollar_per_sqft
t.float :dollar_per_unit
t.integer :rp_acc_code
t.integer :rp_property_id
t.integer :real_estate_property_id
t.timestamps
end
add_index :temp_ptps, [:source_id, :source_type]
end
end
It looks like create_table yields an ActiveRecord::ConnectionAdapters::TableDefinition class. This class does not contain the method index. Instead, change_table appears to yield an ActiveRecord::ConnectionAdapters::Table class which includes this index method.
If you want to add an index during a create_table migration, try this:
class CreateStatistics < ActiveRecord::Migration
def self.up
create_table :statistics do |t|
t.string :name
t.integer :item_id
t.integer :value
t.text :desc
t.timestamps
end
add_index :statistics, :name
add_index :statistics, :item_id
end
def self.down
drop_table :statistics
end
end

Resources