I have two models: Show and Venue. Show has one venue while each venue belongs to show. This condition is defined in both model files with has_one & belongs_to statements properly. However, I'm not able to access the venue by doing show.venue. Consider the following code where s is a Show instance:
logger.info("*********************")
logger.info("#{s.inspect}")
logger.info("#{Venue.find(s.venue_id)}") # Works
logger.info("#{s.venue}") # Causes a MySQL Error
logger.info("*********************")
I feel like the line that causes the MySQL error should work. This is the error:
ActiveRecord::StatementInvalid (Mysql::Error: Unknown column 'venues.show_id' in 'where clause': SELECT * FROM `venues` WHERE (`venues`.show_id = 95) LIMIT 1)
I have no idea why it is trying to access venues.show_id. Any ideas?
You have the foreign keys reversed. In ActiveRecord's conventions, the class with the belongs_to should map to the database table with the foreign key. See the ActiveRecord API: "The belongs_to association is always used in the model that has the foreign key." This makes some sense, if you think about the way that belongs_to interacts with both has_one and has_many (as you obviously can't put the foreign keys in the has_many model).
Related
I'm trying to get an active record association working for two tables that do not have a plural form but still can imply multiple ( Equipment and JobEquipment)
I keep getting the following error when I try and get the Equipment from a the JobEquipment object. The relationship is 1 to Many ( 1 piece of equipment can have Many Job Equipment instances)
job_equipment.equipment
NoMethodError: undefined method `fetch_value' for nil:NilClass
Currently my models look like this
class JobEquipment < ApplicationRecord
self.table_name = "job_equipment"
belongs_to :equipment, :class_name=>"Equipment"
// I tried adding the :class_name=>model to indicate to active record that this would be the plural name as well but no luck.
end
class Equipment < ApplicationRecord
self.table_name = 'equipment'
has_many :job_equipment, :class_name => "JobEquipment" // I don't believe this has_many association is required but I was running out of ideas so I've added it just incase.
end
The JobEquipment table has the equipment_id.
What am I missing here? All my other associations work but the tables all have plural names. I've tried a few things to get this to work. I even tried to use Equipments and JobEquipments but Rails/Active record still threw an error.
I feel like there must be a way to do this as I think a table named equipment would be very common.
Any help would be much appreciated, strangely I couldn't find any resources indicating others having issues with associations on non-plural form tables
First post I've ever felt I had to make here, normally my questions are answered by just reading other posts but this time I think I'm in too deep to find the proper answer, I've been looking for quite a while. I may have multiple issues going on in my code.
I'm a novice with RoR, just started working with it the last couple of months. I'm attempting to run a test query to make sure my associations are working properly, and based on the errors I'm getting, I feel like I've messed up something simple. I'm setting up a couple of tables for a webapp, I'll focus on 2 tables for now because a fix to this can be applied elsewhere afterwards.
Pertinent information:
-I'm using Devise for user authentication
-I have a pto_requests_controller.rb and registrations_controller.rb (registrations is used with devise as a user controller)
-In the database, the table names are 'users' and 'pto_requests'
I have a pto_request model (filename is 'pto_request.rb'):
class PtoRequest < ApplicationRecord
belongs_to :user, optional: true
end
And a user model (filename is 'user.rb'):
class User < ApplicationRecord
has_many :pto_requests
end
To create associations in the database, I used this migration:
class AddUsersToPtorequests < ActiveRecord::Migration[5.1]
def change
add_reference :pto_requests, :users, foreign_key: true
end
end
The foreign key was created in the 'pto_requests' table and called 'users_id'
I can query the tables individually with no issues, but once I try to access data like, for example, user.fname through pto_requests, it errors out. As an example query I've tried:
<%= PtoRequest.joins(:user)
.select('user.fname as user_name').first.user_name%>
I receive the following error:
Mysql2::Error: Unknown column 'user.fname' in 'field list': SELECT user.fname >as user_name FROM pto_requests INNER JOIN users ON users.id = >pto_requests.user_id ORDER BY pto_requests.id ASC LIMIT 1
My current theory is it has something to do with an issue in the end of the generated SQL syntax as it is looking for 'user_id' but this does not exist, only 'users_id' does. Any help is greatly appreciated, and if any more information is required please let me know.
You have missunderstood the associations completely.
belongs_to creates a one-to-one or one-to-many association and places the foreign key column on this models table:
class PtoRequest < ApplicationRecord
belongs_to :user, optional: true
end
This association thus will reference pto_requests.user_id. You have added the foreign key to the wrong table.
To generate the correct migration run:
rails g migration add_user_to_pto_requests user:references
The enitity you are referencing should always be singular.
I'm running into an issue when trying to associate two records via a belongs_to:
class Enrollment < ActiveRecord::Base
belongs_to :offering,
foreign_key: [:term_id, :class_number]
end
#enrollment = Enrollment.new
#enrollment.offering = Offering.last
This throws:
ActiveModel::MissingAttributeError: can't write unknown attribute `[:term_id, :class_number]'
What am I doing wrong?
Rails unfortunately does not support composite keys. If you need something like this, you'd better go with a custom :has_many like #yannick's comment cites.
On the other side, you could do it with a model that's backed by a view, using a table (say my_offerings) which has a rails-friendly ID, and the two PK columns from the other table (term_id, class_number) and join it with the other table in code.
Then, have a small process that parses the offerings table, and builds any missing my_offering record.
In the end the view will have an ID, and the join in the view (that's transparent for rails) will deal with the composite key.
We recently upgraded our rails app from version 3.0.3 to 3.1.0. The application runs successfully for the most part as it did before with one major exception. We have a many-to-many relationship between two models, SurveyDatum and SubGroup, joined via a model called SubGroupSurveyDatum. Here is the code for each:
class SurveyDatum < ActiveRecord::Base
has_many :sub_group_survey_data
has_many :sub_groups, :through => :sub_group_survey_data
end
class SubGroup < ActiveRecord::Base
has_many :sub_group_survey_data
has_many :survey_data, :through => :sub_group_survey_data
end
And as you might expect:
class SubGroupSurveyDatum < ActiveRecord::Base
belongs_to :survey_datum
belongs_to :sub_group
end
If I have a SurveyDatum object that I retrieved previously from the database (lets call it 'sd'), and I invoke the sub_groups method (sd.sub_groups), this is the resulting sql query generated by active record:
SELECT `sub_groups`.* FROM `sub_groups` INNER JOIN `sub_group_survey_data` ON `sub_groups`.`id` = `sub_group_survey_data`.`sub_group_id` WHERE `sub_group_survey_data`.`survey_datum_id` IS NULL
The "IS NULL" part is obviously where the id of my survey data object is supposed to go, however active record fails to use it. The object does indeed have an id, since as mentioned it was persisted and retrieved from the database. This problem only cropped up after we moved to rails 3.1, so I assume there's something I've not done properly in accordance with the new version, but I have no idea. Any ideas? Thank you in advance for your help!
Hmm I used rails 3.1.0 and tried to replicate but all was well. The only case was when I manually set id = nil on the record retrieved from the db. Then I got:
SELECT "authors".* FROM "authors" INNER JOIN "relations" ON "authors"."id" = "relations"."author_id" WHERE "relations"."post_id" IS NULL
What database are you using? I was trying this with sqlite3. Also watch out for certain gems especially those that work with ActiveRecord. I had trouble with this in the past.
We discovered the issue. I had forgotten that the survey_data table has a composite primary key. When we upped to version 3.2.3, and added in the SurveyDatum model the following:
set_primary_key :id
The query finally built and executed properly.
Does anyone know the way, or a place where I can find out how to do this?
Basically, all I want to do is connect a foreign key between two tables.
Is it true, that all I have to do is write the "belongs_to" and "has many" ?
You also need to ensure that a column exists for the foreign key in the database table associated with the Class that says it "belongs_to" the other one. So for the classes...
Class Tree
belongs_to :forest
end
Class Forest
has_many :trees
end
...Rails assumes that your trees table has a forest_id column. You can then do, for example,
my_tree = Tree.find(1)
my_trees_forest = my_tree.forest
Here's a great place to get the info you need: http://guides.rubyonrails.org/association_basics.html