I've got three models: user, product and order. The associations are as follows:
a User (seller) has many Products
a User (buyer) has many Orders
an Order has one Product
an Order has one User (buyer)
a Product has one User (seller)
a Product has one Order
Now in the product model there's an association to a user:
belongs_to :seller, class_name: "User", foreign_key: "seller_id"
in the products_controller for adding a new product linking it to a user:
def create
#product = current_user.products.create(product_params)
....
In the database the foreign key has also been renamed to "seller_id".
When the current_user.products line is called the response fails
ActiveRecord::UnknownAttributeError (unknown attribute 'user_id' for Product.):
app/controllers/products_controller.rb:23:in `create'
I'm not sure how to change the current_user to products association to use this seller_id key. Any help would be much appreciated, thanks.
The :foreign_key option you have in your Product.belongs_to actually needs to be over on User.has_many, ie., in User:
has_many :products, foreign_key: :seller_id
Related
In my product_users joint table there is a role column besides the product_id and user_id.
I have this association in my product model.
has_many :owners, -> { where(product_users: { role: "owner" }) },
through: :product_users, source: :user
All of the products will have only one "owner" and the rest will be "member".
What association should I use to to get the owner of the product instead of an owners collection. So in the views I wanna use product.owner. I couldn't figure out how to use either has_one or belongs_to.
I could use this instance method, but I guess it would be better to define a fine association somehow.
def owner
owners.first
end
I guess the easiest way to do that, would be to add a column "owner_id" to the product. Then, on the product:
belongs_to :owner
and on the user something like this
has_many :owned_products, class_name: "Product", foreign_key: "owner_id"
The "class_name" tells the association that you will be looking for a "Product" and the foreign_key, will define what column will be used to compare with users id.
If you don't want to add additional column, then you can name association to "has_many :owner", but that's wrong on so many levels, that you shouldn't do it. So in the case you don't want to add additional column, stick to the method.
def owner
owners.first
end
I have 2 models in my project. 1 is Users and 1 is courses.
A user has many courses
and courses has many users.
The main problem is that I can't figure out how to assign users to courses without creating a new course.
user = User.first
course = Course.new(title:"course01")
My output would then be something like
Course id: 2, title: "course01", created_at: "2016-03-20 07:05:23",
updated_at: "2016-03-20 07:05:23", user_id: 1>
Now I can't figure out how to add another user to this same course.
user = User.second
?
Remove user_id from courses table, no need of it
Create join table for HABTM
create_table :users_courses, id: false do |t|
t.references :course
t.references :user
end
In user.rb file
has_and_belongs_to_many :courses
In course.rb file
has_and_belongs_to_many :users
after creating new course
course = Course.create(title:"course01")
users = User.all or whatever you need to assign to same course
users.each do |user|
course.users << user ##assign
end
In rails console
course = Course.first or Course.find(1) or whatever you want
course.users << User.find(1) or whatever you want
Let's say a new 'UserCourseAssignment' is created when a user is assigned to a course.
You could create a new UserCourseAssignment model with attributes user_id & course_id to store which users are assigned to which courses. This new table will have a new entry every time a user is assigned to a course.
User model
has_many :user_course_assignments
has_many :courses, through: :user_course_assignments
Course model
has_many :user_course_assignments
has_many :users, though: :user_course_assignments
UserCourseAssignment model
belongs_to :user
belongs_to :course
Edit:
I think you currently have user_id attribute in Course model. You won't need it after implementing the has_many :through association.
i have two tables
1)Properties :fields are id, name, propert_type,category_id
2)Admins : fields id, name,mobile,category_id
i want to write an active record to list all properties , where category_id in properties table and category_id in Admins table are equal, according to current_user_id
i am listing this property list by logging as admin.
model relation
class Category < ActiveRecord::Base
has_many :admins,dependent: :destroy
has_many :properties,dependent: :destroy
end
class Admin < ActiveRecord::Base
belongs_to :category
has_many :properties
end
class Property < ActiveRecord::Base
belongs_to :admin
belongs_to :category
end
i wrote active record like this , but i got error,
can anyone please suggest me a solution for this
#properties= Property.where('properties.category_id=?','admins.category_id=?').and('admins.id=?',current_user.specific.id)
With your assosciation,You can use a sub query for getting your result in one line
#properties = Property.where(category_id: Admin.select("category_id").where(id: current_user.id))
As per my understanding current_user is an Admin. So You can search by the category_id of current_user. If I'm right, try this
#properties = Property.where(category_id: current_user.category_id)
I have a comment system with two tables: comments, and users. On the comment I want to record who the author was and also I want to notify any user that is mentioned in the comment with (#username). So I'm thinking I need to have an author_id on the comment, and also a comments_users table with the comment id and all the users ids that were mentioned. Would this be a correct way to accomplish it?:
User:
has_many :comments
Comment:
belongs_to :users, class_name: 'User', foreign_key: 'author_id'
has_many :users
The associations could be set up thus:
#app/models/user.rb
Class User < ActiveRecord::Base
has_many :comments
has_and_belongs_to_many :mentions, join_table: "comments_users", association_foriegn_key: "comment_id"
end
Class Comment < ActiveRecord::Base
belongs_to :author, class_name: "User", foreign_key: "author_id"
has_and_belongs_to_many :mentions, join_table: "comments_users", foreign_key: "comment_id"
end
#comments_users
comment_id | user_id
This will allow you to call:
#user.comments #-> shows comments user has authored
#user.mentions.first.comment #-> shows first comment user was mentioned in
#comment.author #-> shows user who authored comment
#comment.mentions.first.user #-> shows first user who was mentioned in comment
Update
HABTM still needs a table (Rails migration for has_and_belongs_to_many join table), but the difference is that it doesn't need a primary key column (just comment_id | user_id)
We've created a "self-referential" habtm relationship, meaning you don't need to "create" any records -- they should all be created already. The HABTM will just reference them. As such, you'll need to use the << ActiveRecord method to add records into your mentions collection:
#app/controllers/comments_controller.rb
Class CommentsController < ActiveRecord::Base
def create
#comment = Comment.new(comments_params)
#comment.save_with_mentions
end
end
#app/models/comment.rb
Class Comment < ActiveRecord::Base
def save_with_mentions
comment = self.save
#do something to find mentioned users
mentioned_users = User.where("user_id = 1") #example
for user in mentioned_users do
comment.mentions << user
end
end
end
There are always many ways to accomplish any given task, but I'm guessing you're looking for something like this for your models & associations.
User:
has_many :comments
The user model association looked right.
Comment:
belongs_to :author, class_name: 'User', foreign_key: 'user_id'
has_many :users
Note, the belongs_to should reference a model in singular-naming style (ie: user vs users). I think you're going to want to do a reference like comment.author to find the author of your comments. It is more typical to provide a foreign_key of user_id when referring to a User model to keep things clear, but then provide a clarifying association name like "author" or "creator" or whatever for reference as I showed above. So your Comments table would have a foreign_key of user_id to reference back to the Users table. This user would be referenced in Rails by the name "author".
The second part of your question that has to do with tracking other user references in your model sounds like a one-to-many from the comment-users table. So, that sounds like one option. Similar to your "author" comment, you may want to provide a clearer name like "tags" which can just be references to users.
Another good option for this feature may be to set up a polymorphic table (essentially a flexible join table) if you plan to use this principle elsewhere in your app (like for referencing/tagging people in other elements like a photo or posting or something). It could provide greater flexibility for adding features and tracking these user references. A polymorphic table could have any name, but usually has an "-able" type name - like "taggable". Here's a useful reference: http://guides.rubyonrails.org/association_basics.html#polymorphic-associations
I have the following models:
Users (id, name, email, instance_id, etc...)
Instances (id, domain name)
Books (id, name, user_id, instance_id)
In Rails 3, When a new book is created, I need the user_id, and instance_id to be populated based on the current_user.
Currently, user_id is being assigned when I create a new book but not instance_id? What needs to happen in rails to make that field get filled out on book creation?
Also, shouldn't rails be error'ing given that I can create books without that instance_id filled out?
thxs
It looks like you have de-normalized User and Book models by adding reference to Instance model. You can avoid the redundant reference unless you have a specific reason.
I would rewrite your models as follows:
class Instance < ActiveRecord::Base
has_many :users
has_many :books, :through => :users, :order => "created_at DESC"
end
class User < ActiveRecord::Base
belongs_to :instance
has_many :books, :order => "created_at DESC"
end
class Book < ActiveRecord::Base
belongs_to :user
has_one :instance, :through => :user
end
Now to create a new book for a user.
current_user.books.build(...)
To get a list of the books belonging to user's instance:
current_user.instance.books
To get a list of the books created by the user:
current_user.books
Make sure you index the instance_id column in users table and user_id column in books table.
Rails will only produce an error in this case if (a) you have a validation that's failing, or (b) you have database foreign keys that aren't being satisfied.
What's an instance? i.e. if instance_id is to be populated based on the current user, what attribute of the user should supply it? (the instance_id? why?)