I'm not sure if I fully wrap my mind around this. I want to create a relationship between stores and documents.
In the document table I want a reference to the store and account that created it. To do this would I run this migration
rails g AddStoreToDocuments store:references
and then in the model, specify foreign_keys of account_id and store_id?
like this?
has_many :stores, foreign_key: "store_id"
What is the correct way?
I suggest you to read rails guide on migration.
You can generate the reference by using
rails g migration AddStoreRefToDocuments store:references
rake db:migrate
This will generate the migration. Your models should have association mentioned to make it work
Class Store < ActiveRecord::Base
has_many :documents
end
Class Document < ActiveRecord::Base
belongs_to :store
end
Your documents table should have reference to both tables.
rails g AddStoreToDocuments store:references account:references
relation should be store has_many documents and account has_many documents.
So in Document model :
belongs_to :store
belongs_to :account
in Store model :
has_many :documents
in Account model :
has_many :documents
In the document table I want a reference to the store and account
that created it.
Your relationship should be belongs_to instead of has_many:
belongs_to :store
belongs_to :account
Notice that, since you are following ActiveRecord conventions, you don't need to specify any foreign key (it will use store_id and account_id).
And has_many relationship should be used in both Store and Account models:
has_many :documents
You will also need to update your migration (or create a new one) to add account:references.
firstly, your migration would throw an error, it should be
rails g migration AddStoreToDocuments store:references
generated migration looks like
def change
add_reference :documents, :store, index: true, foreign_key: true
end
then do,
rake db:migrate
which will automatically create a column store_id in your documents table, so in your documents.rb
belongs_to :store
belongs_to :account #this you might already be having I suppose
Related
I'm having difficulty with bulding attributes within my model. I keep seeing this error
NoMethodError: undefined method `users' for #<ActiveRecord::ConnectionAdapters::SQLite3::TableDefinition:0x00007f9d9ad9df98>
I need attributes that look like this:
#group.rb
class Spree::Group < ActiveRecord::Base
has_many :users
end
#user_decorator.rb
Spree::User.class_eval do
belongs_to :group, class_name: "Spree::Group"
end
For group.rb I ran
rails g model Spree::Group
and I got:
class Spree::Group < ApplicationRecord
has_many :users
end
I'm confused on how to add 'has_many :users' without actually going into the
model and inputting it there.
For the user_decorator I'm not sure what that migration would look like. Any help would be fantastic!
You could call:
rails g model group user:references
which will generates an user_id column in the groups table and will modify the group.rb model to add a belongs_to :user relatonship. Please note, you must to put manually the has_many :groups or has_one :group relationship to the user.rb model.
If you already have the model generated, you could create a migration with the following:
rails g migration AddUserToGroup user:belongs_to
which will generate:
class AddUserToGroup < ActiveRecord::Migration
def change
add_reference :groups, :user, index: true
end
end
the only difference with this approach is, the belongs_to :user relationship in the group.rb model won't be created automatically, so you must create it for your own.
Could somebody explain me is my code correct.
I'm trying to get foreign_key option in rails associations.
I have 2 models:
Book and Author
Book db schema:
name
user_id
Author db schema:
name
My models:
class Author < ApplicationRecord
has_many :books, foreign_key: :user_id
end
class Book < ApplicationRecord
belongs_to :author, foreign_key: :user_id
end
Here I don't understand why we should define foreign_key in both models. Is it necessarily?
If you have used the table and column names that Rails expects, then you do not need to explicitly define the foreign_key. In your case, if the foreign key column was named author_id, then you could get by quite simply:
class Author < ApplicationRecord
has_many :books
end
class Book < ApplicationRecord
belongs_to :author
end
However, in your case, the foreign key column is not named according to what Rails expects, so you have needed to explicitly define the foreign key column name. That's fine, but it does make a little more work for you.
In cases where you have explicitly defined the foreign key, you should define it for both associations. Your has_many association will not work without it.
In addition, you should define the inverse association:
class Author < ApplicationRecord
has_many :books, foreign_key: :user_id, inverse_of: :author
end
class Book < ApplicationRecord
belongs_to :author, foreign_key: :user_id, inverse_of: :books
end
Defining the inverse_of can cause ActiveRecord to make fewer queries, and gets rid of a few surprise behaviors. For an explanation of inverse_of, see Exploring the :inverse_of Option on Rails Model Associations by Ryan Stenberg
I have a User model and a Question model.
I want to add a belongs_to :user association to the Question model, but I want that association to be called author. For example, I would call question.author rather than question.user.
Obviously this requires two steps:
The association in the models/question.rb
The migration (note both the user and question tables already exist)
Surprisingly I haven't found the single, conventional method of doing this in Rails 5 in a different answer.
How do I do this?
rails g migration add_user_to_questions user:references
rails db:migrate
Then in model:
class Question < ApplicationRecord # or ActiveRecord::Base
belongs_to :author, class_name: 'User', foreign_key: :user_id
end
Sorry for the basic, basic question but I'm having some trouble understanding the RoR doc.
say I have 3 models--Students, Classes, and Enrolled_in. If it isn't clear, students will enroll in classes, so Enrolled_in should have Students and Classes as foreign keys. I generated the models for each of these, but I'm confused what I should put into the associated migration file vs. the associated model file for each table. Do I specify the columns of the table in the migration file, and the key constraints in models?
If someone could clarify this, or tell me how they would solve the example question I posted, that would be really helpful. Thanks.
Firstly, to follow the convention the model name should be EnrolledIn, not Enrolled_in. Better yet, change it to Enrollment or something that has a definite meaning as a noun. And you're also going to run into trouble trying to use Class (which is already a ruby object) as a model name. Perhaps change it to Course or something similar.
That aside, you should define all columns in your migrations. You can define the enrolled_ins table like this:
add_table :enrolled_ins do |t|
t.references :student
t.references :course # I'm using course instead of class as noted above
end
The references shortcut will add a :student_id and :course_id as integer fields.
In your model files you'll have:
# student.rb
class Student < ActiveRecord::Base
has_many :enrolled_ins
has_many :courses, :through => :enrolled_ins
end
# course.rb
class Course < ActiveRecord::Base
has_many :enrolled_ins
has_many :students, :through => :enrolled_ins
end
# enrolled_in.rb
class EnrolledIn < ActiveRecord::Base
belongs_to :student
belongs_to :course
end
I recently started creating a site where users will be able to join groups and be able to interact with the group. So far I have used devise for the users but I'm now wondering what do I use to create user profiles and even the groups profile. This is my first rails application and I just need some guidance on where to go from here? What tools will I need? What is the best way of doing this?
Rails is the only tool you need. First you'll need to create the other models in your application. From your description I see a UserProfile and a Group. Rails' generator command will stub those out for you:
$ rails generate model UserProfile
$ rails generate model Group
$ rails generate model Membership
Now you will have user_profile.rb and group.rb in your app/models directory, as well as migrations in db/migrate/create.rb. Next you'll need to tell rails what fields to create in the database by editing the migration script. You are free to include whatever you wish here, but you will at least want foreign keys to relate your data.
def CreateUserProfiles < ActiveRecord::Migration
create_table :user_profiles do |t|
t.belongs_to :user
...
and
def CreateMemberships < ActiveRecord::Migration
create_table :memberships
t.belongs_to :user
t.belongs_to :group
...
Now you can execute your migrations to create the database tables for you:
$ rake db:migrate
And you can use ActiveRecord association class methods to define those relationships in code, so that Rails will take care of the SQL for you.
app/models/membership.rb
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :group
end
app/models/user.rb
class User < ActiveRecord::Base
has_one :user_profile
has_many :memberships
has_many :groups, :through => :memberships
...
end
app/models/group.rb
class Group < ActiveRecord::Base
has_many :memberships
has_many :users, :through => :memberships
end
app/models/user_profile.rb
class UserProfile < ActiveRecord::Base
belongs_to :user
end
Now you have all the tools in place that you need to give users profiles:
UserProfile.create(:user => User.first, :attr => "value", ...)
Or to put a user in a group:
group = Group.create(:name => "Group 1")
group.users << User.first
Use tools when they save you time, but learn to use the tool on which they all depend first–Rails. Check out the Rails Guides, they are excellent.