I currently have a Subscriber
model and a Comment
model. The Subscriber
has_many comments
and the comment
belongs_to Subscriber
. All I want is for a Subscriber to be able to make a comment in a text field and that comment belongs to that Subscriber through an id. For some reason I can't not figure this out and I'm having a tough time getting help. So, to be very clear I have a subscriber_id
on the comment
model, how do I attach them together so that I can make this call in the Rails Console - @comment = @subscriber.comments.first
and see the first comment that belongs to that particular subscriber? I'll show some code for clarity.
SCHEMA:
create_table "comments", force: :cascade do |t|
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "fav_drink"
t.string "visit_time"
t.integer "subscriber_id"
end
create_table "subscribers", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.string "email"
t.string "phone_number"
t.string "birthdate"
t.string "street_1"
t.string "street_2"
t.string "city"
t.string "zip"
t.string "state"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "visit"
end
CONTROLLERS:
class CommentsController < ApplicationController
def new
@comment = Comment.new
end
def create
@comment = Comment.create(comments_params)
if @comment.save
flash[:notice] = "Thank you!"
redirect_to subscribers_search_path(:comments)
else
render "new"
end
end
private
def comments_params
params.require(:comment).permit(:fav_drink, :subscriber_id)
end
end
class SubscribersController < ApplicationController
def index
@subscriber = Subscriber.all
end
def new
@subscriber = Subscriber.new
end
def create
@subscriber = Subscriber.create(subscriber_params)
if @subscriber.save
flash[:notice] = "Subscriber Has Been Successfully Created"
redirect_to new_subscriber_path(:subscriber)
else
render "new"
end
end
And the Models are as described in the intro. Thank You!
There are several ways of going about this. I'd highlight 3 below:
Use a nested resource routes, for example:
resources :subscribers do resources :comments end
Using this approach your routes would become subscribers/1/comments... and in your comments_controller, you can fetch your subscriber from params[:subscriber_id]
If the subscriber is the current_user, you could as well set it in your comments_controller as such:
current_user.comments.create(comments_params)
Use a hidden field in your comments/form
to set the subscriber.
Basically, looking at your comments_params
, you're requiring the subscriber_id
, which is not being passed to the controller. So you need a way of passing this down.
You could set your subscriber before the create/new
action and then do:
@subscriber.comments.[create|new]
then in your new
comments form view, you would have f.hidden_field :subscriber_id
Let me know if that works.
There are multiple approaches:
Approach 1: Using current_user/ logged_in user
If the subscriber is supposedly logged into the system, and if the current_user is the reference to the logged_in subscriber, then you could assign the current_user to the comment before creating.
class CommentsController < ApplicationController
def new
@comment = Comment.new
end
def create
@comment = current_user.comments.build(comments_params)
if @comment.save
flash[:notice] = "Thank you!"
redirect_to subscribers_search_path(:comments)
else
render "new"
end
end
private
def comments_params
params.require(:comment).permit(:fav_drink)
end
end
Approach 2: Hidden Field
Set a subscriber_id hidden_field in the comments form and then your existing implementation should work fine. Just for clarify I am copy/pasting your implementation.
class CommentsController < ApplicationController
def new
@comment = Comment.new
end
def create
@comment = Comment.new(comments_params)
if @comment.save
flash[:notice] = "Thank you!"
redirect_to subscribers_search_path(:comments)
else
render "new"
end
end
private
def comments_params
params.require(:comment).permit(:fav_drink, :subscriber_id)
end
end
Approach 3: Nested Resource
Using the rails
nested resource, set your routes to the following:
resources :subscribers
resources: comments, only: [:new, :create]
end
Then update your controller code to the following:
class CommentsController < ApplicationController
def new
@comment = Comment.new
end
def create
@subscriber = Subscriber.find(params[:subscriber_id])
@comment = @subscriber.comments.build(comments_params)
if @comment.save
flash[:notice] = "Thank you!"
redirect_to subscribers_search_path(:comments)
else
render "new"
end
end
private
def comments_params
params.require(:comment).permit(:fav_drink)
end
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.