I have three models: Almon, Bela and Lingo
class Almon < ActiveRecord::Base
belongs_to :bela, dependent: :destroy
has_many :lingos, through: :bela, dependent: :delete_all
accepts_nested_attributes_for :bela
accepts_nested_attributes_for :lingos, :allow_destroy => true
end
I am trying to submit a nested form in Almon and I am getting
Cannot modify association 'Almon#Lingos' because the source reflection class 'Lingo' is associated to 'Bela' via :has_many.
Could anyone please tell me what I am doing wrong?
You need to use has_many instead of belongs_to as the following:
has_many :belaes, dependent: :destroy
has_many :lingoes, through: :belaes, dependent: :delete_all
Related
I'ved got a Ruby on Rails app
I have Block that has_many Unit that has_many User through user_unit_assocs.
The model is define as such.
class Block < ActiveRecord::Base
has_many :units, dependent: :destroy
class Unit < ActiveRecord::Base
belongs_to :block
has_many :users, :through => :user_unit_assocs, dependent: :destroy
has_many :user_unit_assocs, dependent: :destroy
class User < ActiveRecord::Base
has_many :units, :through => :user_unit_assocs
has_many :user_unit_assocs, dependent: :destroy
The problem is when I delete Block
- unit gets deleted
- user_unit_assoc gets deleted
- BUT the user of the unit DOES NOT GET DELETED
How do I solve this problem to make sure it cascade block to user as well. Problem is the through but I cant change now the table structure, how can I solve these dependent records deletion properly. Thanks.
I have 3 tables
class Product < ApplicationRecord
has_many :accessories
has_many :product_attribute_categories, through: :accessories, dependent: :destroy
end
class Accessory < ApplicationRecord
belongs_to :product
belongs_to :product_attribute_category
end
class ProductAttributeCategory < ApplicationRecord
has_many :accessories, dependent: :destroy
has_many :products, through: :accessories
has_many :product_attributes, dependent: :destroy
now when I try to delete a ProductAttributeCategory, I want all the accessories that it is associated with to be deleted. So it wont return any errors.
However it returns Accessory is marked as readonly. So I'm wondering if what I'm doing is not optimal and what I should do instead.
Run.rb:
has_many :schedule_machines, through: :schedule_locations
Schedule.rb:
has_many :schedule_locations, dependent: :destroy
has_many :schedule_machines, through: :schedule_locations
has_many :assigned_schedule_machines, through: :runs, source: :schedule_machines
has_many :runs, dependent: :destroy
when I look at a Schedule in the console,
schedule.assigned_schedule_machines
gives an undefined method.
How come?
has_many :runs, dependent: :destroy
has_many :assigned_schedule_machines, through: :runs, source: :schedule_machines
You need to order the "runs" first. The assigned_schedule wants to use runs; but in your original code the runs wasn't defined yet.
I have a many-to-many relation between User and "Link".
The join model is called LinkAddress and besides for saving the IDs of the other two models, it has an attribute called address - information it collects at creation.
How can I access the address attribute for a certain link in a request scenario like the following: User.first.links.first.address ?
Models:
class User < ActiveRecord::Base
has_many :link_addresses, dependent: :destroy
has_many :links, through: :link_addresses
accepts_nested_attributes_for :link_addresses, allow_destroy: true
end
class LinkAddress < ActiveRecord::Base
belongs_to :user
belongs_to :link
end
class Link < ActiveRecord::Base
has_many :link_addresses, dependent: :destroy
has_many :users, through: :link_addresses
end
You could access it through User since it's a has_many ... :through relation:
User.first.link_addresses.first.address
Or, if you'd like to go through links then:
User.first.links.first.link_addresses.first.address
SQL Aliases
I had this exact question: Rails Scoping For has_many :through To Access Extra Data
Here's the answer I got:
#Images
has_many :image_messages, :class_name => 'ImageMessage'
has_many :images, -> { select("#{Image.table_name}.*, #{ImageMessage.table_name}.caption AS caption") }, :class_name => 'Image', :through => :image_messages, dependent: :destroy
This uses SQL Aliases which I found at this RailsCast (at around 6:40 in). It allows us to call #user.image.caption (even though .caption is in the join model)
Your Code
For your query, I'd use this:
class User < ActiveRecord::Base
has_many :link_addresses, dependent: :destroy
has_many :links, -> { select("#{Link.table_name}.*, #{LinkAddress.table_name}.address AS address") }, through: :link_addresses
accepts_nested_attributes_for :link_addresses, allow_destroy: true
end
This will allow you to write #user.links.first.address, and gracefully handles an absence of the address record
I'm not sure what has changed getting this error when trying to login:
ERROR: relation "tags" does not exist
LINE 1: SELECT DISTINCT "tags".* FROM "tags" INNER JOIN "taggings" O...
The tag model:
class Tag < ActiveRecord::Base
attr_accessor :unread_count, :user_feeds
has_many :taggings
has_many :feeds, through: :taggings
end
The tagging model:
class Tagging < ActiveRecord::Base
belongs_to :tag
belongs_to :feed
belongs_to :user
end
And the user relationships:
class User < ActiveRecord::Base
has_one :coupon
has_many :subscriptions, dependent: :delete_all
has_many :feeds, through: :subscriptions
has_many :entries, through: :feeds
has_many :imports, dependent: :destroy
has_many :billing_events, as: :billable, dependent: :delete_all
has_many :taggings, dependent: :delete_all
has_many :tags, through: :taggings
has_many :sharing_services, dependent: :delete_all
has_many :unread_entries, dependent: :delete_all
has_many :starred_entries, dependent: :delete_all
has_many :saved_searches, dependent: :delete_all
has_many :actions, dependent: :destroy
belongs_to :plan
end
This error is new and came right after I tried to install the intercom.io gem. I removed the gem, did a gem cleanup, reset the db and still the same error.
Not sure what happened, if anyone has any suggestions I would appreciate it.
Checked missing tables, and that was the problem.