What is the problem with this association?
My association looks like this:
class Quote < ApplicationRecord
has_many :language_pairs
end
class LanguagePair < ApplicationRecord
belongs_to :quote
belongs_to :w_flow
has_many :w_flow_steps, through: :w_flow
end
class WFlow < ApplicationRecord
has_many :language_pairs
has_many :w_flow_steps
end
class WFlowStep < ApplicationRecord
belongs_to :w_flow
end
When i run
q=Quote.find(1)
q.language_pairs.create!(source_language:'French - EU', w_flow_id: 1)
I have following errors:
ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection: Cannot modify association 'LanguagePair#w_flow_steps' because the source reflection class 'WFlowStep' is associated to 'WFlow' via :has_many.
If you want to create a LanguagePair a related with a particular Quote, first you need to get the Quote that you want to be associated:
q = Quote.find(1)
Then you pass that variable to the create method of your LanguagePair:
lp = LanguagePair.create!(quote: q, source_language:'French - EU', w_flow_id: 1)
And Rails will take care about the relations.
Note: you are using create! that will raise an exception if the record is invalid
Related
These are obviously not my actual Models but they serve as an example. I have the following class definitions.
class Movie < ActiveRecord::Base
has_one :opening
has_one :opening_info, through: :opening
end
class Opening < ActiveRecord::Base
belongs_to :movie
has_one :opening_info
end
class OpeningInfo < ActiveRecord::Base
belongs_to :opening
# OpeningInfo has a opening_date attribute in the DB
end
I want to find all movies that have a valid Opening, a valid OpeningInfo through that Opening, and that OpeningInfo has a opening_date that is not nil. By valid I mean it exists. I have tried several expressions using joins and includes but it complains of illegal sql statements. Any ideas?
This should probably work, when opening_infos is the table name:
Movie.joins(:opening_info).where.not(opening_infos: { opening_date: nil })
So I have these four classes:
class User < ActiveRecord::Base
has_many :water_rights
end
class WaterRight < ActiveRecord::Base
belongs_to :user
has_many :place_of_use_area_water_rights
has_many :place_of_use_areas, through: :place_of_use_area_water_rights
end
class PlaceOfUseAreaWaterRight < ActiveRecord::Base
belongs_to :place_of_use_area
belongs_to :water_right
end
class PlaceOfUseArea < ActiveRecord::Base
has_many :place_of_use_area_water_rights
has_many :water_rights, through: :place_of_use_area_water_rights
end
and I call User.first.water_rights and get a collection of WaterRights. My question is how do I get a collection of PlaceOfUseAreas associated with those WaterRights without doing something like this:
areas = []
water_rights.each do |wr|
areas << wr.place_of_use_areas
end
areas.flatten.uniq{ |a| a.id }
This works but it makes a new query for every single WaterRight. I'm looking for a way to make one query to get the collection of associated PlaceOfUseAreas.
You just want to get all associated PlaceOfUseAreas objects in single query, right?
If so, Rails have pretty single line solution for it:
PlaceOfUseArea.joins(:water_wights).uniq
Read more about joins method if you want more information.
I am trying to get an activerecord association through 2 layers of has_one associations and cannot quite figure it out.
I have 3 models:
class Dialog < ActiveRecord::Base
belongs_to :contact
end
class Contact < ActiveRecord::Base
has_many :dialogs
belongs_to :location
end
class Location < ActiveRecord::Base
has_many :contacts
end
I would like to create a scope in the Dialog model that allows me to pass in the id of a Location and get all Dialogs created by Contacts from the given Location... something like:
Dialog.from_location(Location.first.id)
I can get a non-activerecord array of the desired result using select:
Dialog.all.select{|s| s.contact.location_id == Location.first.id }
But I need this to return an activerecord array so that other scopes or class methods can be called on the result. I have tried using joins and includes, but am confused after reading the rails guides on how to use them.
Can anyone help me figure out how to construct a scope or class method that will accomplish this?
Thanks in advance
Just adding a note to the answer you accepted, quoting from the ruby on rails guides website:
Using a class method is the preferred way to accept arguments for scopes. These methods will still be accessible on the association objects ( link )
So in your condition, instead of doing a scope with an argument, define a method :
class Contact < ActiveRecord::Base
has_many :dialogs
belongs_to :location
def self.from_location(id)
where(location_id: id)
end
end
You can define your scopes as follows:
class Dialog < ActiveRecord::Base
belongs_to :contact
scope :from_location, -> (id) do
where(contact_id: Contact.from_location(id).select(:id))
end
end
class Contact < ActiveRecord::Base
has_many :dialogs
belongs_to :location
scope :from_location, ->(id) do
where(location_id: id)
end
end
I have 3 model,and their relation is many-to-many
MMem:
class MMem < ActiveRecord::Base
has_many :t_mem_task_records
has_many :m_tasks,through: :t_mem_task_records
end
TMemTaskRecord:
class TMemTaskRecord < ActiveRecord::Base
belongs_to :m_mem
belongs_to :m_task
end
TMemTask:
class TMemTask < ActiveRecord::Base
has_many :t_mem_task_records
has_many :m_mems,through: :t_mem_task_records
end
If I want to get all TMemTasks of specified MMem,I can write:
MMem.find(1).m_tasks
Now,I want to add a TMemTask to specified MMem
MMem.find(1).m_tasks.create(MTask.find(1))
But I got an error:
NoMethodError: undefined method `stringify_keys' for #<MTask:0xb822624>
Why I got this error? or any other solution?
.create is used to create a new MTask, if you want to add an existed MTask to the association, then use:
MMem.find(1).m_tasks << MTask.find(1)
I have following database schema:
I want to be able to do something like this:
dog.head << Feature.new(...)
dog.tail << Feature.new(...)
I am new to Rails, so I am not always sure by 100% what I am writing, but I tried following declaration of Dog class, and failed :) :
class Dog < ActiveRecord::Base
has_many :features, :through=>:dog_features
has_many :head_features, :through=>:dog_features, :class_name=>'Feature', :conditions=>{:group=>1}
has_many :tail_features, :through=>:dog_features, :class_name=>'Feature', :conditions=>{:group=>2}
end