Rails has_many_belongs_to, has_many :through - ruby-on-rails

I have 3 Models: Place, User, Reviews. Place and Users related with has_many_belongs_to - for favorites, and has_many :through - for reviews.
I want to insert to favorites some place, but this place inserted to reviews table, what is wrong?
Or create model Favorites?
class Place < ActiveRecord::Base
has_and_belongs_to_many :users
has_many :reviews
has_many :users, through: :reviews
end
class User < ActiveRecord::Base
has_and_belongs_to_many :places
has_many :reviews
has_many :places, through: :reviews
end
class Review < ActiveRecord::Base
belongs_to :user
belongs_to :place
end
class FavoritesController < ApplicationController
def add_favorites
if User.first.places.push(Place.find(params[:place_id]))
render json: {desc:true, status:0, error:nil}
else
render json: {desc:false, status:1, error: "Problem insert to table places_users"}
end
end

Have you try having different names for the associations? Right now both your favorites and reviewed places are called the same.
Try something like:
class User < ActiveRecord::Base
has_and_belongs_to_many :favorite_places
has_many :reviews
has_many :reviewed_places, through: :reviews
end
And for the controller:
User.first.favorite_places.push(Place.find(params[:place_id]))

You could always use active record serializers to store a array of favorites ids in the User model.
class User < ActiveRecord::Base
serialize :favorites
end
user = User.create(favorites: [1, 4, 8, 9])

Related

Setting up Rails model

I have a User model, Post model and Bookmark model. How do i need to set up relationship among them so that I can use current_user.bookmarks.posts.
Maybe:
class User < ApplicationRecord
has_many :bookmarks
end
class Bookmark < ApplicationRecord
belongs_to :user
has_many :posts
end
class Post < ApplicationRecord
belongs_to :bookmark
end
If you're wanting to get all the posts that belong to the user, then you can use the has_many :through association:
class User < ApplicationRecord
has_many :bookmarks
has_many :posts, through: :bookmarks
end
class Bookmark < ApplicationRecord
belongs_to :user
has_many :posts
end
class Post < ApplicationRecord
belongs_to :bookmark
end
Then you can just call:
user = User.first
all_posts = user.posts
It will return an array containing all the posts for each of the bookmarks belonging to the user.

Many to many relationship ActiveRecord::HasManyThroughAssociationNotFoundError

Hi I'm trying to set up a many to many relationship in my app. I have two models Count.rb
class Count < ApplicationRecord
has_many :users, through: :counts_users
end
users.rb:
class User < ApplicationRecord
has_many :counts, through: :counts_users
end
and counts_users.rb:
class CountsUser < ApplicationRecord
belongs_to :user
belongs_to :count
end
Now I can create a count
Count.new(message: 'hello')
but if I then do
Count.last.users << User.last
I get the error ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association :counts_users in model ErrorCount
I assume I've done something wrong setting up the association, but I'm not sure what?
Your models' associations should be set up like this:
# count.rb
class Count < ApplicationRecord
has_many :counts_users
has_many :users, through: :counts_users
end
# user.rb
class User < ApplicationRecord
has_many :counts_users
has_many :counts, through: :counts_users
end
# counts_user.rb
class CountsUser < ApplicationRecord
belongs_to :user
belongs_to :count
end
See: the Rails Guides on has_many :through Association

Arrange items in an array by the time they were added to that array?

Basically I have a Collection model and a Post model, where a Collection has many posts and a Post belongs to many collections. So I'll occasionally push posts to the #collection.posts array using <<, to replicate a post being added to a collection. Now is there a way to order the posts in #collection.posts by the time they were pushed to that array? If yes, how?
All relevant models:
user.rb
class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
has_many :collections, dependent: :destroy
end
post.rb
class Post < ActiveRecord::Base
belongs_to :user
has_many :collectables
has_many :collections, through: :collectables
end
collection.rb
class Collection < ActiveRecord::Base
belongs_to :user
has_many :collectables
has_many :posts, through: :collectables
end
collectable.rb
class Collectable < ActiveRecord::Base
belongs_to :post
belongs_to :collection
end
I guess adding an order scope to the definition of the association would work:
# in collection.rb
has_many :posts,
-> { order('collectables.created_at DESC') },
through: :collectables

search ActiveRecord through rails association

I have 2 models:
User and Book
and a join model ownership which connect User and Book
class Book < ActiveRecord::Base
has_many :ownerships
has_many :users, :through => :ownerships,:uniq=>true
...
end
class User < ActiveRecord::Base
has_many :ownerships
has_many :books, :through => :ownerships
end
class Ownership < ActiveRecord::Base
belongs_to :user
belongs_to :book
end
The scenario is that when user A is searching for books on my website,I return the related books which are owned by users around user A(for example,they are both in the same university).
Can I do that with rails accociation?
thanks #Mark Guk
what i finally do is :
scope :same_university,lambda{|q,current_user|
where("title like '%#{q}%'").joins(:sell_infos).where(
"sell_infos.university is '#{current_user.university}'")
}

has_many inheritance

I have a model called company that has_many users then users belongs_to company.
class Company < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :company
end
If something belongs to users will it also belong to company?
You have to use has_many :through association for this.
class Comment < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
belongs_to :company
has_many :comments
end
class Company < ActiveRecord::Base
has_many :users
has_many :comments, :through => :users
end
Now you can do the following:
c = Company.first
c.users # returns users
c.comments # returns all the comments made by all the users in the company

Resources