NoMethodError Rails 5 - ruby-on-rails

I am trying to allow users to bookmark various coffee shops. I have successfully managed to allow users to favorite coffee shops, so was trying to follow the same steps, but I get a NoMethodError when trying to load Coffeeshops#show.
My code:
user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :validatable,
has_many :comments
has_many :coffeeshops
has_many :favorite_coffeeshops # just the 'relationships'
has_many :favorites, through: :favorite_coffeeshops, source: :coffeeshop
has_many :bookmarked_coffeeshops # just the 'relationships'
has_many :bookmarks, through: :bookmarked_coffeeshops, source: :coffeeshop
coffeeshop.rb
class Coffeeshop < ApplicationRecord
has_many :comments, as: :commentable
belongs_to :roaster
belongs_to :user
has_many :favorite_coffeeshops# just the 'relationships'
has_many :favorited_by, through: :favorite_coffeeshops, source: :user
has_many :bookmarked_coffeeshops# just the 'relationships'
has_many :bookmarked_by, through: :bookmarked_coffeeshops, source: :user
bookmarked_coffeeshop.rb
class BookmarkedCoffeeshop < ApplicationRecord
belongs_to :coffeeshop
belongs_to :user
end
coffeeshop.show.html.erb
<%= link_to "Bookmark", bookmarked_coffeeshops_path(#coffeeshop, type: "bookmarked"), method: :put %>
Migration
class CreateBookmarkedCoffeeshops < ActiveRecord::Migration[5.0]
def change
create_table :bookmarked_coffeeshops do |t|
t.integer :coffeeshop_id
t.integer :user_id
t.timestamps
end
end
end
Error
undefined method `bookmarked_coffeeshop_path' for #<#<Class:0x007fadb9ccad30>:0x007fadc3232e90>

Schoolboy error - I hadn't updated my routes:
Adding:
resources :coffeeshops do
put :bookmarked, on: :member
end
resolved the issue.

Related

ActiveRecord::HasManyThroughAssociationNotFoundError cannot get the posts for each user for some reason Rails

In the rails console I am inputing User.first.posts and i am getting this error ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association :likes in model User
from
USER MODEL
class User < ApplicationRecord
has_secure_password
has_many :posts
has_many :comments
has_many :posts, through: :likes
validates :name, presence: true, uniqueness: true
end
POSTS MODEL
class Post < ApplicationRecord
belongs_to :user
has_many :comments
has_many :likes
has_many :users, through: :likes
def number_of_comments
comments.length
end
def number_of_likes
likes.length
end
end
LIKES MODEL
class Like < ApplicationRecord
belongs_to :user
belongs_to :post
end
Im only showing you the likes model because its popping up in the error but i just want all the posts for each user so if i type User.first.posts all their posts will show up
You need to actually define the likes assocation that you're defining the indirect assocation through:
class User < ApplicationRecord
# ...
has_many :likes # this was missing
has_many :posts, through: :likes
end
But you also have two different assocations between users and posts that are sharing the same name - you actually need something more like:
class User < ApplicationRecord
has_many :posts # posts that this user has created
has_many :likes
has_many :liked_posts,
through: :likes,
source: :post
end
There's seems to be a typo in your User model. There are 2 associations for posts.
class User < ApplicationRecord
has_secure_password
has_many :posts
has_many :comments
# has_many :posts, through: :likes # <-- this i think is the culprit.
# it should be like this:
has_many :likes, through: :posts
validates :name, presence: true, uniqueness: true
end

Rails polymorphic comments associate

Trying to work out an polymorphic association where Comments can belong to, for example, Photos and Users. Where a Comment on a user is treated as a "direct message". But I'm getting the User association a bit messed up.
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
class Photo < ActiveRecord::Base
has_many :comments, as: :commentable, dependent: :destroy
end
class User < ActiveRecord::Base
has_many :comments, dependent: :destroy
has_many :messages, as: :commentable
end
This is incorrect. Ideally, user.comments should retrieve all Comment records where user_id == user.id and something like user.messages should retrieve all Comments where the type is User and they are the subject.
Relationships:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
belongs_to :user
end
class Photo < ActiveRecord::Base
has_many :comments, as: :commentable, dependent: :destroy
end
class User < ActiveRecord::Base
has_many :comments, dependent: :destroy
has_many :messages, as: :commentable, class_name: 'Comment'
end
Schema:
# Comments
...
t.integer :user_id
t.integer :commentable_id
t.string :commentable_type
...
Then you can invoke:
#user.comments # Get all comments created by particular user
#user.messages # Get all comments where particular user is a subject
have you added the foreign key and type columns to the comments table? within a migration file:
def change
add_column :comments, :commentable_type, :integer
add_column, :commentable_type, :string
add_index :comments, [:commentable_type, :commentable_id]
end
Also make sure you have a Message model and it has the associations
class Message < ActiveRecord::Base
has_many :comments, dependent: :destroy
belongs_to :commentable, polymorphic: true
end

Gem `activity_notification` does not create a new record after getting triggered by an active record

The gem activity_notification is not creating/triggering after I've configured it according to the documentation. I've tried to create the notification in the event of a user creating a comment or replying to an existing comment, but the gem is not created/triggered. Please help me figure out why.
Here's my code
Model User
class User < ApplicationRecord
audited
with_options dependent: :destroy do |assoc|
assoc.has_many :forums, class_name: 'Communication::Forum'
assoc.has_many :favorited_forums, class_name: 'Communication::FavoritedForum'
assoc.has_many :comments
assoc.has_many :likes
end
acts_as_target
end
Model Forum
class Communication::Forum < ApplicationRecord
audited
belongs_to :user
acts_as_commentable
has_many :likes, as: :likeable
has_many :favorited_forums, class_name: "Communication::FavoritedForum"
end
Model Comment
class Comment < ActiveRecord::Base
audited
acts_as_nested_set scope: [:commentable_id, :commentable_type]
belongs_to :commentable, polymorphic: true
acts_as_notifiable :users,
targets: ->(comment, key) {
([comment.commentable.user] + [comment.user]).uniq
}
end

Migration has_one and has_many

class Post < ActiveRecord::Base
has_one :owner, class_name: "User", foreign_key: "owner_id" #creator post
has_many :users #followers post
end
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :posts
end
What command line I need to perform to migrate to perform these different relationships between the User and Post tables?
Thanks
Post should belong_to:owner, because the posts table has the foreign key. Also, its #users is a bit too ambiguously named, as is User#posts.
Here are your models:
class Post < ActiveRecord::Base
belongs_to :owner, class_name: 'User', inverse_of: :owned_posts # foreign_key: :owner_id will be inferred
has_many :subscriptions
has_many :followers, through: :subscriptions, source: :user, class_name: 'User', inverse_of: :followed_posts
end
class Subscription < ActiveRecord::Base
belongs_to :post
belongs_to :user
end
class User < ActiveRecord::Base
has_many :owned_posts, class_name: 'Post', inverse_of: :owner
has_many :subscriptions
has_many :followed_posts, through: :subscriptions, source: :post, class_name: 'Post', inverse_of: :followers
end
And here are the migrations to support them:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
# ...
end
end
end
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.integer :owner_id
# ...
end
end
end
class CreateSubscriptions < ActiveRecord::Migration
def change
create_table :subscriptions do |t|
t.integer :post_id
t.integer :user_id
end
end
end
If it weren't for the 'ownership' relation, you could use a has_and_belongs_to_many relationship:
rename the subscriptions migration to posts_users (must be plurals in alphabetical order),
do away with its model entirely, and
have Post.has_and_belongs_to_many :users and User.has_and_belongs_to_many :posts.
In fact, you technically could do that, but having ambiguous names like that is bad practice.

Creating a favorite list in rails with devise

i have a problem to solve in my application here a little brief:
My app is something like AirBnb so i have Users and Houses, any user can create a house i already have this, i need a watch list, is a list of houses who user liked like a Bookmark or Favorite system, i have the house list and the idea is have button like "watch this" when user clicks this house go to their watch lists.
I've seen many solutions and i tried them, i understand the relationship but i don't know how do get pieces in.
here is my code currently:
watch.rb:
class Watch < ActiveRecord::Base
belongs_to :user
belongs_to :house
end
user.rb:
class User < ActiveRecord::Base
has_many :houses, :dependent => :destroy
has_many :watches, :dependent => :destroy
has_many :watch_houses, :through => :watches, :source => :houses
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
house.rb:
class House < ActiveRecord::Base
belongs_to :user
has_many :watches, :dependent => :destroy
has_many :watches, :through => :watches, :source => :user
end
routes.rb:
Rails.application.routes.draw do
resources :houses
devise_for :users
resources :users, :only => [:show] do
resources :watches
end
resources :houses
root 'home#index'
end
How can i create a link to assing the user and the house in the watchlist cliking in the house list?
Here's how to do it:
#config/routes.rb
resources :houses do
post :watch #-> url.com/houses/:house_id/watch
end
#app/controllers/houses_controller.rb
class HousesController < ApplicationController
def watch
#house = House.find params[:house_id]
current_user.watched_houses << #house
redirect_to #house, notice: "Added to Watch List"
end
end
Here are the models:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :houses, dependent: :destroy
has_many :watching, class_name: "Watch", foreign_key: :user_id, dependent: :destroy
has_many :watched_houses, through: :watching
end
#app/models/house.rb
class House < ActiveRecord::Base
belongs_to :user
has_many :watches, dependent: :destroy
has_many :watchers, through: :watches, foreign_key: :user_id
end

Resources