Reputation: 2321
I am using gem devise for creating user profiles. Every user can create comments in any profile I want to add each user name under the comment he wrote.
A user has many comments
A user has many profile comments, this is the relationship between a user and the comments This is the error that I got when I create a comment
can't write unknown attribute `user_id`
Here is what I did
class CreateProfileComments < ActiveRecord::Migration
def change
create_table :profile_comments do |t|
t.timestamps null: false
end
end
end
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.text :text
t.references :user, index: true, foreign_key: true
t.timestamps null: false
end
end
end
in user.rb model
has_many :comments
has_many :profile_comments, dependent: :destroy
in comment.rb
class Comment < ActiveRecord::Base
belongs_to :user #not users as you have defined in your question
has_many :profile_comments
end
in profile comment.rb
class ProfileComment < ActiveRecord::Base
belongs_to :comment
belongs_to :user
end
in comment controller
class CommentsController < ApplicationController
before_action :find_comment ,only:[:show,:update,:edit,:destroy]
def new
@user =User.find(params[:id])
@comment = @user.comments.build
end
def index
end
def create
@user =User.find(params[:id])
@comment = current_user.comments.build(comment_params)
@profile_comment = ProfileComment.new
@user.profile_comments < @profile_comment
@comment.profile_comment < @profile_comment
if @comment.save
redirect_to doctor_path(:id => @user.id)
end
end
def edit
end
def update
if @comment.update(comment_params)
redirect_to root_path, alert: "user Information updated successfully"
else
flash.now[:error] = "Couldn't update!"
render :edit
end
end
def destroy
@comment.destroy
redirect_to doctors_path, notice: "comment deleted Successfully"
end
private
def find_comment
@comment = Comment.find(params[:id])
end
def comment_params
params.require(:comment).permit(:text)
end
end
in user profile view
<% @user.profile_comments.each do | profile_comment |%>
<%comment = profile_comment.comment%>
<% if comment.text.present? %>
<%= comment.text %><br>
<%if comment.user.blank?%>
No user assigned to this comment
<%else%>
<%= comment.user.name #or email or whatever%>
<%end%>
<br><hr>
<% end %>
<% end %>
Upvotes: 0
Views: 1412
Reputation: 102055
I'm guessing what you actually want is just to create two assocations pointing to the same table:
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.text :text
t.references :user, index: true, foreign_key: true
t.references :author, index: true, foreign_key: { to_table: :users }
t.timestamps null: false
end
end
end
Here user_id
references the target user of the comment and author_id
references the user writing the comment. Both reference users.id
.
Then create two belongs_to
associations in your comment model:
class Comment < ApplicationRecord
belongs_to :user
belongs_to :author,
class_name: 'User',
inverse_of: :authored_comments
end
And two has_many
associations in your User model:
class User < ApplicationRecord
# comments about this user
has_many :comments
# comments written by this user
has_many :authored_comments,
class_name: 'Comment',
foreign_key: :author_id,
inverse_of: :author
end
I have no idea why you would want to mix in another table as both relations are one to many.
class CommentsController < ApplicationController
before_action :set_user, only: [:new, :create]
# ...
def new
@comment = @user.comments.new
end
def create
@comment = @user.comments.new(comment_params) do |c|
c.author = current_user
end
if @comment.save
redirect_to doctor_path(id: @user.id)
else
render :new
end
end
private
def set_user
@user = User.find(params[:id])
end
# ...
end
If you then want to display comments you would do:
<% @user.comments.each do |comment| %>
<div class="comment">
<div class="body">
<%= comment.body %>
</div>
<p class="author"><%= comment.author.email %></p>
</div>
<% end %>
Upvotes: 1