Can't access related table - ruby-on-rails

I am really under pressure and totally new to Rails. Project due in two days.
I have done a search on Rails console for a user inputted in my database user = user.find(1) and it returns.
the user has_many recipes
recipes belongs to user ....defined in user and recipe models respectively.
I am getting the error.
undefined method "recipe" for user?
This is how I created my User
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.integer "position"
t.boolean "visible", :default => false
t.string "restaurant_name", :limit => 25
t.string "username", :limit => 25
t.string "password", :limit => 50
t.string "hashed_email", :default => "", :null => false
t.string "address1", :limit => 80
t.string "address2", :limit => 80
t.string "address3", :limit => 80
t.string "county", :limit => 40
t.string "telephone", :limit => 40
t.text "web address", :limit => 60
t.string "photo_path", :limit => 100
t.text "description", :limit => 2000
t.text "salt", :string, :limit => 50
t.timestamps
end
end
def self.down
drop_table :users
end
end
Recipe
class CreateRecipes < ActiveRecord::Migration
def self.up
create_table :recipes do |t|
t.integer "user_id"
t.string "recipe_name", :limit => 100
t.integer "greedy_type", :default => 0
t.string "photo_path", :limit => 40
t.text "description", :limit => 400
t.text "recipe", :limit => 4000
t.integer "ingredient1", :limit => 40
t.integer "ingredient2", :limit => 40
t.integer "ingredient3", :limit => 40
t.integer "ingredient4", :limit => 40
t.string "permalink"
t.integer "position"
t.boolean "visible", :default => false
t.timestamps
end
add_index("recipes", "user_id")
add_index("recipes", "permalink")
end
def self.down
drop_table :recipes
end
end
users.rb
class Users < ActiveRecord::Base
has_many :recipes
end
recipe.rb
class Recipes < ActiveRecord::Base
belongs_to :users
has_many :restaurants
end
ERROR
irb(main):005:0> users.recipe
NoMethodError: undefined method `recipe' for #<Users:0x599ebc0>
from C:/RailsInstaller/Ruby1.8.7/lib/ruby/gems/1.8/gems/activemodel-3.0.9/lib/active_model/attribute_methods.rb:
392:in `method_missing'
from C:/RailsInstaller/Ruby1.8.7/lib/ruby/gems/1.8/gems/activerecord-3.0.9/lib/active_record/attribute_methods.r
b:46:in `method_missing'

If User has_many recipes, why you add field recipe_id for user? You should add user_id field to the Recipe class table. After creating recipe just store user_id and that is all you need. Cheers!

as user has many recipes,
you have to write something like to get first users recipe..
recipe = user.recipes.first
and store user_id in recipe table.

Related

Association problems in between models RAILS 4

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

Why wont counter_cache work

class FixedLineItem < AR
belongs_to :fee_table, :class_name => 'FixedFeeTable',
:foreign_key => 'fixed_fee_table_id',
:inverse_of => :line_items,
:counter_cache => :fixed_line_items_count
end
class FixedFeeTable < AR
has_many :line_items, :class_name => 'FixedLineItem',
:inverse_of => :fee_table
end
Given the above, why does #fixed_fee_table.line_items.size still access the db? I can see it performing a COUNT operation in the console.
If i rename the has_many association to has_many :fixed_line_items, it works as expected.
Am i missing an option somewhere? I cant find any mention through googling however.
EDIT
This is on rails 3.2.14
and my schema for the two tables
create_table "fixed_fee_tables", :force => true do |t|
t.string "kind"
t.integer "total_amount_cents"
t.integer "fee_summary_id"
t.string "currency"
t.integer "final_total_amount_cents"
t.integer "fixed_line_items_count", :default => 0, :null => false
end
create_table "fixed_line_items", :force => true do |t|
t.string "description"
t.integer "quantity"
t.integer "price_cents"
t.integer "fixed_fee_table_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "amount_cents"
t.integer "position"
t.integer "total_adjustment_cents"
t.string "currency"
end

Rails comment out migration file for development?

I'm running this migration file on local and running into problems because part is MySQL which does not work because I'm using Sqlite3. I want to make sure the SQL runs only in production not in development. I understand I need to wrap part of this with this comment so that I can successfully run this migration:
unless Rails.env == "development".
How can I add this to the script below?
class Places < ActiveRecord::Migration
def self.up
create_table :countries do |t|
t.string :name, :limit => 50, :null => false
t.string :fips104, :limit => 2, :null => false
t.string :iso2, :limit => 2, :null => false
t.string :iso3, :limit => 3, :null => false
t.string :ison, :limit => 4, :null => false
t.string :internet, :limit => 2, :null => false
t.string :capital, :limit => 25
t.string :map_reference, :limit => 50
t.string :nationality_singular, :limit => 35
t.string :nationaiity_plural, :limit => 35
t.string :currency, :limit => 30
t.string :currency_code, :limit => 3
t.integer :population
t.string :title, :limit => 50
t.string :comment, :limit => 255
t.timestamps
end
create_table :regions do |t|
t.references :country, :null => false
t.string :name, :limit => 45, :null => false
t.string :code, :limit => 8, :null => false
t.string :adm1code, :limit => 4, :null => false
t.timestamps
end
create_table :cities do |t|
t.references :country, :null => false
t.references :region, :null => false
t.string :name, :limit => 45, :null => false
t.float :latitude, :null => false
t.float :longitude, :null => false
t.string :timezone, :limit => 10, :null => false
t.integer :dma_id
t.string :county, :limit => 25
t.string :code, :limit => 4
t.timestamps
end
add_index :cities, :name
execute "LOAD DATA INFILE '#{RAILS_ROOT}/db/migrate/Countries.txt' INTO TABLE countries
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\r\n' IGNORE 1 LINES;"
execute "LOAD DATA INFILE '#{RAILS_ROOT}/db/migrate/Regions.txt' INTO TABLE regions
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\r\n' IGNORE 1 LINES;"
execute "LOAD DATA INFILE '#{RAILS_ROOT}/db/migrate/Cities.txt' INTO TABLE cities
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\r\n' IGNORE 1 LINES;"
end
def self.down
drop_table :countries
drop_table :regions
drop_table :cities
end
end
In your self.up method you can check environment like below:
if Rails.env.production?
#your mysql code which runs only in production env
end

How do I write the opposite of this migration?

My migration right now :
class CreateActivities < ActiveRecord::Migration
def self.up
create_table :activities do |t|
t.integer :account_id, :null => false
t.integer :target_id, :null => false
t.string :target_type, :null => false
t.string :event_type, :null => false
t.integer :employee_id
t.string :name
t.timestamps
end
add_index :activities, [:target_id, :target_type]
With this I can now call a target like so :
Activity.first.target
And it will bring up the target_id, based on the target_type.
How would I do the opposite of that so that I can select a target, and if it has any associated Activities, they will show up?
Like so :
Job.find(1234).activities
# Where Job.find(1234) is the target_id of many activities.
If I understand right, this should do it:
class Job < ActiveRecord::Base
has_many :activities, :conditions => ['target_type = ?', 'Job'], :as => :target
end

Getting ActiveRecord::RecordNotUnique but then not able to find the existing record

I have something like the following code. (Model names changed as they're not important to what's happening.)
The #find_or_create_bar_for_blah_id works fine most of the time. Occasionally it will return nil though and I'm not sure why.
It's some kind of race condition as the problem happens in resque jobs that run as part of our app.
Any clues as to how #find_or_create_bar_for_blah_id could return nil?
class Foo < ActiveRecord::Base
has_many :bars, :dependent => :destroy
def find_or_create_bar_for_blah_id(locale_id)
begin
bars.where(:blah_id => blah_id).first || bars.create!(:blah_id => blah_id)
rescue ActiveRecord::RecordNotUnique
bars.where(:blah_id => blah_id).first
end
end
end
class Bar < ActiveRecord::Base
belongs_to :foo
validates_uniqueness_of :blah_id, :scope => :foo_id
end
# db/schema.rb
create_table "bars", :force => true do |t|
t.integer "foo_id"
t.integer "blah_id"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "bars", ["foo_id", "blah_id"], :name => "index_bars_on_foo_id_and_blah_id", :unique => true
add_index "bars", ["foo_id"], :name => "index_bars_on_foo_id"
create_table "foos", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "foos", ["name"], :name => "index_foos_on_name"
Doh! This was because we were using update_attribute in part of the code, which of course doesn't run AR validations. embarrassed face

Resources