My models
CAR BRANDS MODEL
class CarBrand < ActiveRecord::Base
has_many :car_ads
end
CAR ADVERTISEMENTS MODEL
class CarAd < ActiveRecord::Base
has_one :car_brand
end
my controller:
def index
#car_ads = CarAd.all.order("car_ads.created_at DESC")
end
car ads migrations:
class CreateCarAds < ActiveRecord::Migration
def up
create_table :car_ads do |t|
t.integer "user_id"
t.integer "car_brand_id"
t.integer "car_model_id"
t.integer "state_id", :limit => 2
t.integer "vin_id"
t.integer "year_manufac", :precision => 4
t.integer "km_age"
t.integer "price_usd", :limit => 7
t.integer "car_tel_number", :precision => 8
t.float "motor_volume", :limit => 10
t.string "transmission"
t.integer "horse_power", :limit => 3
t.text "description"
t.boolean "visible", :default => true
t.boolean "active", :default => true
t.string "photo_file_name"
t.string "photo_content_type"
t.integer "photo_file_size"
t.datetime "photo_updated_at"
t.timestamps null: false
end
add_index :car_ads, :user_id
add_index :car_ads, :car_brand_id
add_index :car_ads, :car_model_id
add_index :car_ads, :state_id
add_index :car_ads, :vin_id
end
def down
drop_table :car_ads
end
end
Car brands migratiions
class CreateCarBrands < ActiveRecord::Migration
def up
create_table :car_brands do |t|
t.string "brand", :limit => 20
t.timestamps null: false
end
end
def down
drop_table :car_brands
end
end
so the problem is that i cant get car brand form car ads, please help,
i wanted to get that like
iterating
<% #car_ads.each do |carad|%>
<%= carad.car_brand %>
<%end%>
Modify CAR ADVERTISEMENTS MODEL
class CarAd < ActiveRecord::Base
belongs_to :car_brand
end
Modify your controller:
def index
#car_ads = CarAd.all.order("created_at DESC")
end
You didn't add any reference to CarBrand in CarAd table, just add the car_ad_id column with a migration like this
class AddCarBradIdToCarAd < ActiveRecord::Migration
def change
add_column :car_ads, :car_brand_id, :integer
end
end
So rails would be able to get the corresponding CarBrand from a CarAd
Related
So I am struggling with this error. While building a react on rails project.
Completed 500 Internal Server Error in 75ms (ActiveRecord: 6.1ms)
ActiveModel::UnknownAttributeError (unknown attribute 'product_id' for >Property.):
When I run this controller:
class SendDataController < ApplicationController
protect_from_forgery with: :null_session
def save
product = Product.create(name:params[:name], upc:params[:upc].to_i, available_on:params[:availableon])
property = product.Properties.build(name:params[:properties][0][:name])
property.save
end
end
I have tried to things found here and here. But I am getting no where. Below is my current setup.
Models:
class ProductProperty < ApplicationRecord
belongs_to :Property
belongs_to :Product
end
class Product < ApplicationRecord
has_many :Properties
has_many :ProductProperties
end
class Property < ApplicationRecord
belongs_to :Product
has_one :ProductProperty
end
Migration:
class CreateProducts < ActiveRecord::Migration[5.2]
def change
create_table :products do |t|
t.string :name
t.string :upc
t.datetime :available_on
t.timestamps
end
end
end
class CreateProperties < ActiveRecord::Migration[5.2]
def change
create_table :properties do |t|
t.string :name
t.timestamps
end
end
end
class CreateProductProperties < ActiveRecord::Migration[5.2]
def change
create_table :product_properties do |t|
t.string :value
t.timestamps
end
end
end
class AddProductRefToProperties < ActiveRecord::Migration[5.2]
def change
add_reference :properties, :Product, foreign_key: true
end
end
class AddProductRefToProductProperties < ActiveRecord::Migration[5.2]
def change
add_reference :product_properties, :Product, foreign_key: true
end
end
class AddPropertiesRefToProductProperties < ActiveRecord::Migration[5.2]
def change
add_reference :product_properties, :Property, foreign_key: true
end
end
Schema:
ActiveRecord::Schema.define(version: 2018_09_24_163027) do
create_table "product_properties", force: :cascade do |t|
t.string "value"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "Product_id"
t.integer "Property_id"
t.index ["Product_id"], name: "index_product_properties_on_Product_id"
t.index ["Property_id"], name: "index_product_properties_on_Property_id"
end
create_table "products", force: :cascade do |t|
t.string "name"
t.string "upc"
t.datetime "available_on"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "properties", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "Product_id"
t.index ["Product_id"], name: "index_properties_on_Product_id"
end
end
Thanks for any help you can give me!
ActiveModel::UnknownAttributeError (unknown attribute 'product_id' for
Property.)
It says there is no product_id in properties table. That is true because you have Product_id instead of product_id, so is the error.
Rails Conventions
By default, attribute names should be snakecase. You should generate a migration which will change Product_id to product_id and migrate as to fix the error. You should also change association names to snakecase as well. For instance
belongs_to :Property
belongs_to :Product
should be
belongs_to :property
belongs_to :product
2 Models => Town and Island
# Town.rb
belongs_to :player
belongs_to :island
# Island.rb
has_many :towns
The connection occurs via 2 different integer variables
:island_x
:island_y
e.g. :island_x => 34 :island_y => 43
How can i set this association up ?
# CreateIslands
create_table :islands, id: false do |t|
t.primary_key :grepo_id
t.integer :island_x
t.integer :island_y
t.integer :type_number
t.integer :available_towns
t.timestamps
end
# CreateTowns
create_table :towns, id: false do |t|
t.primary_key :grepo_id
t.integer :player_id
t.string :name
t.integer :island_x
t.integer :island_y
t.integer :slot
t.integer :points
t.timestamps
end
Something like this
Class Town < ActiveRecord::Base
belongs_to :player
belongs_to :island ,foreign_key :island_x
end
Update
I see there is no use of island_x and island_y in both the schemas.You can just have a normal foreign_key island_id in the towns table and you can make a call town.island or island.towns.
Update1
I got it wrong with foreignn_key above.You can just make a method and make the matching like this
def some_method
#island_x = Island.find(params[:island_x])
#island_y = Island.find(params[:island_x])
#town_x = Town.where(:island_x => #island_x.id)
#town_y = Town.where(:island_y => #island_y.id)
end
I'm trying to use a :has_many :through type association, but I'm getting the following error:
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: work_units.developer_id:
Many other posts about this sort of thing have just had spelling mistakes, but I've checked mine.
class Developer < ActiveRecord::Base
attr_accessible :skype_name, :language_ids, :user_attributes
has_many :work_units
has_many :projects, :through => :work_units
...
end
class Project < ActiveRecord::Base
attr_accessible :complete, :description, :finalised, :price
has_many :work_units
has_many :developers, :through => :work_units
...
end
class WorkUnit < ActiveRecord::Base
attr_accessible :hours_worked
belongs_to :project
belongs_to :developer
end
I've run db:migrate and it didn't complain. I did make a mistake and had to rollback the db then re-migrate, but I think I did it right. I use the annotate gem and it doesn't show any of the relationship ids I'd expect. So, do I need to create a WorkUnits table or am I missing something? The rails guide didn't mention manually making tables.
Edit
Here's the migration I used to create the WorkUnit model and stuff:
class CreateWorkUnits < ActiveRecord::Migration
def change
create_table :work_units do |t|
t.integer :hours_worked, :default => 0
t.timestamps
end
end
end
Edit 2
Snippets from my schema.rb:
create_table "work_units", :force => true do |t|
t.integer "hours_worked", :default => 0
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "projects", :force => true do |t|
t.string "description"
t.decimal "price", :precision => 8, :scale => 2
t.boolean "complete", :default => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
Similarly for :developers. So, why doesn't my migration add the association information for me?
Your WorkUnit migration should look like this:
class CreateWorkUnits < ActiveRecord::Migration
def change
create_table :work_units do |t|
t.integer :hours_worked, :default => 0
t.references :developer
t.references :project
t.timestamps
end
add_index :work_units, :developer_id
add_index :work_units, :project_id
end
end
You need to add the foreign keys to your work_units table.
class CreateWorkUnits < ActiveRecord::Migration
def change
create_table :work_units do |t|
t.integer :hours_worked, :default => 0
t.integer :project_id, null: false
t.integer :developer_id, null: false
t.timestamps
end
add_index :work_units, :project_id
add_index :work_units, :developer_id
end
end
Another way:
class CreateWorkUnits < ActiveRecord::Migration
def change
create_table :work_units do |t|
t.integer :hours_worked, :default => 0
t.belongs_to :project
t.belongs_to :developer
t.timestamps
end
add_index :work_units, :project_id
add_index :work_units, :developer_id
end
end
You can also define these fields when generating your model, then they'll be added to the migration automatically as show in the second snippet.
$ rails g model WorkUnit hours_worked:integer project:belongs_to developer:belongs_to
Hope that helps.
A table for WorkUnit needs to exist, whether that means it migration was automatically generated via scaffolding or if the migration was manually written by you.
If you don't have a migration yet that creates that table, you'll need to create that migration because the table does need to exist.
You do need a work_units table with a project_id and developer_id column.
Have a look at http://xyzpub.com/en/ruby-on-rails/3.2/activerecord_datenbank_anlegen.html if you don't know how to create a table.
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
I'm a complete rails newbie, so forgive me if this is trivial.
I have an Inventory model that either belongs_to a Store or a Traveling Party:
class Inventory < ActiveRecord::Base
belongs_to :trader, :polymorphic => true
end
class Store < ActiveRecord::Base
has_one :inventory, :as => :trader, :dependent => :destroy
end
class TravelingParty < ActiveRecord::Base
has_many :travelers, :dependent => :destroy
has_one :inventory, :as => :trader, :dependent => :destroy
validates_presence_of :speed, :ration, :position
accepts_nested_attributes_for :travelers, :reject_if => :reject_traveler, :allow_destroy => true
accepts_nested_attributes_for :inventory, :allow_destroy => true
def reject_traveler(attributes)
attributes['profession'].blank? and attributes['name'].blank?
end
end
I created a form that, when submitted, creates a Traveling Party and a number of Travelers. Now I'd like the form to also create an Inventory and initialize all the variables to 0. I know the following doesn't address variable initialization, but it doesn't even seem to put a row of null values into the Inventory database table.
class TravelingPartiesController < ApplicationController
def new
#traveling_party = TravelingParty.new
5.times do
traveler = #traveling_party.travelers.build
end
#inventory = #traveling_party.inventory.create
end
def create
#traveling_party = TravelingParty.new(params[:traveling_party])
if #traveling_party.save
flash[:notice] = "Successfully created traveling party and travelers."
redirect_to '/store/'
else
flash[:error] = "Please specify a leader."
redirect_to '/new/'
end
end
def index
end
end
For good measure, here is what the database schema looks like:
ActiveRecord::Schema.define(:version => 20111018224808) do
create_table "inventories", :force => true do |t|
t.integer "ox"
t.integer "food"
t.integer "clothing"
t.integer "ammunition"
t.integer "money"
t.integer "axle"
t.integer "wheel"
t.integer "tongue"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "trader_id"
end
create_table "stores", :force => true do |t|
t.string "name"
t.integer "location"
t.integer "priceScale"
t.datetime "created_at"
t.datetime "updated_at"
end
# Could not dump table "travelers" because of following StandardError
# Unknown type 'relations' for column 'traveling_party_id'
create_table "traveling_parties", :force => true do |t|
t.integer "speed"
t.integer "ration"
t.integer "position"
t.datetime "created_at"
t.datetime "updated_at"
end
end
Is there a reason the inventory database table isn't being affected at all? And once that works, what would be the best way to initialize a traveling_party.inventory to have all 0s? (i.e., values for ox, food, clothing, etc).
This may because your inventories table does not include a 'trader_type'. This is required for polymorphic associations.
create_table "inventories", :force => true do |t|
t.integer "trader_id"
t.string "trader_type"
end
Edit:
To set all the values initially to 0, the best way would be to put a default value onto the fields in the table. (If you want it to always be initialized to 0 if there is no other option, otherwise they will default to nil)
I believe you can create a migration with
change_table(:inventories) do |t|
t.change :ox, :integer, :default => 0
end