Devise - Trying to display the user who made a post - ruby-on-rails

I'm creating this rails app,
In the app I have the functionality to make an account, then post a status.
I have made it so I can display the status on the screen, but how do i display the name of the person who made the post? I am using devise and have setup :username
My View
<% if user_signed_in? %>
<h1 id="welcome" class="nuvo">Welcome <%= current_user.username %>!</h1>
<% else %>
<h1 id="welcome" class="nuvo">Log-In to make some posts!</h1>
<% end%>
<div class="follow-row">
<div class="titan-users nuvo"><h2>TITAN Users</h2></div>
</div>
<div class="statuses">
<% if user_signed_in? %><div class="status-form"><%= render 'form' %></div><% end %>
<% #posts.each do |post| %>
<div class="post">
<div class="tstamp"><strong>Posted <%= time_ago_in_words(post.created_at) %> ago by <%= current_user.username %></strong></div>
<div class="status"><%= post.status %></div>
</div>
<% end %>
</div>
My Post Controller
class PostsController < ApplicationController
# GET /posts
# GET /posts.json
def index
#posts = Post.all(:order => "created_at DESC")
#post = Post.new
respond_to do |format|
format.html # index.html.erb
format.json { render json: #posts }
end
end
# GET /posts/1
# GET /posts/1.json
def show
redirect_to posts_path
end
# GET /posts/new
# GET /posts/new.json
def new
#post = Post.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #post }
end
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(params[:post])
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render json: #post, status: :created, location: #post }
else
format.html { render action: "new" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PUT /posts/1
# PUT /posts/1.json
def update
#post = Post.find(params[:id])
respond_to do |format|
if #post.update_attributes(params[:post])
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
format.json { head :no_content }
end
end
end
My user model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :username
has_many :post
# attr_accessible :title, :body
end
My Post model
class Post < ActiveRecord::Base
attr_accessible :status, :author
belongs_to :user
validates :status, :presence => true
end
So, does anyone have any ideas how in the view instead displaying, 'current_user.username' can I display the name of the person who posted it?
So, for CodeIt this is the error I get
undefined method `username' for nil:NilClass
Extracted source (around line #17):
14: <% if user_signed_in? %><div class="status-form"><%= render 'form' %></div><% end %>
15: <% #posts.each do |post| %>
16: <div class="post">
17: <div class="tstamp"><strong>Posted <%= time_ago_in_words(post.created_at) %> ago by <%= post.user.username %></strong></div>
18: <div class="status"><%= post.status %></div>
19: </div>
20: <% end %>
20: <% end %>`

You have post belongs_to user. So you can use:
post.user.username #In your #posts loop

In your create method in the controller, i dont see you pass the user_id to it,so probably the user dint set into the post model.
Maybe you can put a hidden_field_tag in your form, and pass your user_id as a param.
Then, in your controller,do something like
#post.user_id = params[:user_id]
Then,in your view,you can access the user_id and find the username from the user_id

Related

Nested fields made with cocoon are not saving

I have 3 objects, Users, Recipes, and Tasks. Tasks are nested inside Recipes, and Recipes are nested inside Users. I am able to save/add/delete Recipes just fine, and I can add Tasks in the HTML form, but when I go to save, the Tasks do not show up as part of a Recipe, even when I go back to the form. I have been working on this for a while and would appreciate any insight.
Users Controller:
class UsersController < ApplicationController
before_filter :authenticate_user_or_admin_or_conduit!
before_action :set_user, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#users = User.all
respond_with(#users)
end
def show
respond_with(#user)
end
def new
#user = User.new
respond_with(#user)
end
def edit
end
def create
#user = User.new(user_params)
if #user.save
if conduit_signed_in?
redirect_to '/conduits', notice: 'User created successfully.'
elsif admin_signed_in?
redirect_to '/admins', notice: 'User created successfully.'
else
redirect_to #user, notice: 'User created successfully.'
end
else
render :new
end
end
def update
#user.update(user_params)
respond_with(#user)
end
def destroy
#user.destroy
respond_with(#user)
end
private
def set_user
#user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
end
Recipes Controller:
class RecipesController < ApplicationController
before_action :set_recipe, only: [:show, :edit, :update, :destroy]
# GET /recipes
# GET /recipes.json
def index
#recipes = Recipe.all
end
# GET /recipes/1
# GET /recipes/1.json
def show
end
# GET /recipes/new
def new
#recipe = Recipe.new
end
# GET /recipes/1/edit
def edit
end
# POST /recipes
# POST /recipes.json
def create
#recipe = Recipe.new(recipe_params)
respond_to do |format|
if #recipe.save
format.html { redirect_to #recipe, notice: 'Recipe was successfully created.' }
format.json { render :show, status: :created, location: #recipe }
else
format.html { render :new }
format.json { render json: #recipe.errors, status: :unprocessable_entity }
end
end
class UsersController < ApplicationController
before_filter :authenticate_user_or_admin_or_conduit!
before_action :set_user, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#users = User.all
respond_with(#users)
end
def show
respond_with(#user)
end
def new
#user = User.new
respond_with(#user)
end
def edit
end
def create
#user = User.new(user_params)
if #user.save
if conduit_signed_in?
redirect_to '/conduits', notice: 'User created successfully.'
elsif admin_signed_in?
redirect_to '/admins', notice: 'User created successfully.'
else
redirect_to #user, notice: 'User created successfully.'
end
else
render :new
end
end
def update
#user.update(user_params)
respond_with(#user)
end
def destroy
#user.destroy
respond_with(#user)
end
private
def set_user
#user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
end
Recipes Controller:
class RecipesController < ApplicationController
before_action :set_recipe, only: [:show, :edit, :update, :destroy]
# GET /recipes
# GET /recipes.json
def index
#recipes = Recipe.all
end
# GET /recipes/1
# GET /recipes/1.json
def show
end
# GET /recipes/new
def new
#recipe = Recipe.new
end
# GET /recipes/1/edit
def edit
end
# POST /recipes
# POST /recipes.json
def create
#recipe = Recipe.new(recipe_params)
end
# PATCH/PUT /recipes/1
# PATCH/PUT /recipes/1.json
def update
respond_to do |format|
if #recipe.update(recipe_params)
format.html { redirect_to #recipe, notice: 'Recipe was successfully updated.' }
format.json { render :show, status: :ok, location: #recipe }
else
format.html { render :edit }
format.json { render json: #recipe.errors, status: :unprocessable_entity }
end
end
end
# DELETE /recipes/1
# DELETE /recipes/1.json
def destroy
#recipe.destroy
respond_to do |format|
format.html { redirect_to recipes_url, notice: 'Recipe was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_recipe
#recipe = Recipe.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def recipe_params
params.require(:recipe).permit(:reward, task_attributes: [:description, :counter, :done, :_destroy, :id])
end
end
Tasks Controller:
class TasksController < ApplicationController
before_action :set_task, only: [:show, :edit, :update, :destroy]
# GET /tasks
# GET /tasks.json
def index
#tasks = Task.all
end
# GET /tasks/1
# GET /tasks/1.json
def show
end
# GET /tasks/new
def new
#task = Task.new
end
# GET /tasks/1/edit
def edit
end
# POST /tasks
# POST /tasks.json
def create
#task = Task.new(task_params)
respond_to do |format|
if #task.save
format.html { redirect_to #task, notice: 'Task was successfully created.' }
format.json { render :show, status: :created, location: #task }
else
format.html { render :new }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /tasks/1
# PATCH/PUT /tasks/1.json
def update
respond_to do |format|
if #task.update(task_params)
format.html { redirect_to #task, notice: 'Task was successfully updated.' }
format.json { render :show, status: :ok, location: #task }
else
format.html { render :edit }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
# DELETE /tasks/1
# DELETE /tasks/1.json
def destroy
#task.destroy
respond_to do |format|
format.html { redirect_to tasks_url, notice: 'Task was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_task
#task = Task.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def task_params
params.require(:task).permit(:description, :counter, :done, :notes)
end
end
Users Model:
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 :characters
end
Recipes Model:
class Recipe < ActiveRecord::Base
belongs_to :character
has_many :task, :dependent => :destroy
accepts_nested_attributes_for :task, allow_destroy: true
end
Tasks Model:
class Task < ActiveRecord::Base
belongs_to :recipe
end
User Form:
<div id="myform">
<%= form_for(#character) do |f| %>
<% if #character.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#character.errors.count, "error") %> prohibited this character from being saved:</h2>
<ul>
<% #character.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<li class="accordion-navigation">
Recipes
<div id="panel6a" class="content">
<fieldset>
<legend>Recipes consist of a variety of tasks</legend>
<div>
<%= f.fields_for :recipe do |recipe| %>
<%= render "recipe_fields", :f => recipe %>
<% end %>
<div class="links">
<%= link_to_add_association "Add Recipe", f, :recipe, :class =>"button" %>
</div>
</div>
</fieldset>
</div>
</li>
<% end %>
</div>
Recipe Form:
<div class="nested-fields">
<div class="row">
<div class="row">
<div class="large-3 columns">
<div class="field">
<%= f.text_field :reward %>
</div>
</div>
<div class="large-9 columns">
<fieldset>
<legend>Add Task</legend>
<div>
<%= f.fields_for :task do |task| %>
<%= render "task_fields", :f => task %>
<% end %>
<div class="links">
<%= link_to_add_association "Add Task", f, :task, :class =>"small button" %>
</div>
</div>
</fieldset>
<span style="float:right"><%= link_to_remove_association "Remove Recipe", f, data: {confirm: "Are you sure?"}, :class =>"button alert" %></span>
</div>
</div>
</div>
</div>
Task Form:
<div class="nested-fields">
<div class="row">
<div class="large-3 columns">
<div class="field">
<%= f.text_field :description %>
</div>
</div>
<div class="large-3 columns">
<div class="field">
<%= f.number_field :counter, label: "Record number if needed" %>
</div>
</div>
<div class="large-3 columns">
<div class="field">
<%= f.check_box :done, label: "Completed?" %>
</div>
</div>
<span style="float:right"><%= link_to_remove_association "Remove Task", f, data: {confirm: "Are you sure?"}, :class =>"small button alert" %></span>
</div>
</div>
I dealt with this funkiness recently. I'm guessing the Task is being created, just not relating to the Recipe. If that is the case, you need to include the recipe_id in the task_attributes array.
Nesting is all sorts of magic, but for whatever reason, the id of the parent object won't be set unless it's explicitly included as a permitted param.
Hope this helps!
The other post definitely pointed out an error, but I could not fix it until I added the task_attributes to the recipe_attributes in the User controller, like so:
params.require(:user).permit(:name, recipe_attributes: [:reward, :_destroy, :user_id, :id, task_attributes: [:description, :recipe_id, :counter, :done, :_destroy, :id]])

NoMethodError in Statuses#new

I'm currently building this website in college for fun. My hope is that it will help the education system. Anyways, I'm still trying to figure out rails. I just set up the devise gem with no problem. However, when I click post a new status it gives me this error:
NoMethodError in Statuses#new
Showing /Users/wyatt/Network/netbook/app/views/statuses/_form.html.erb where line #16 raised:
undefined method `user_name' for #<Status:0x00000101ec36d0>
Extracted source (around line #16):
13:
14: <div class="field">
15: <%= f.label :user_name %><br />
16: <%= f.text_field :user_name %>
17: </div>
18: <div class="field">
19: <%= f.label :content %><br />
So here's what my form looks like:
<%= form_for(#status) do |f| %>
<% if #status.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#status.errors.count, "error") %> prohibited this status from being saved:</h2>
<ul>
<% #status.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :user_name %><br />
<%= f.text_field :user_name %>
</div>
<div class="field">
<%= f.label :content %><br />
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Here's my controller
class StatusesController < ApplicationController
# GET /statuses
# GET /statuses.json
def index
#statuses = Status.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #statuses }
end
end
# GET /statuses/1
# GET /statuses/1.json
def show
#status = Status.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #status }
end
end
# GET /statuses/new
# GET /statuses/new.json
def new
#status = Status.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #status }
end
end
# GET /statuses/1/edit
def edit
#status = Status.find(params[:id])
end
# POST /statuses
# POST /statuses.json
def create
#status = Status.new(params[:status])
respond_to do |format|
if #status.save
format.html { redirect_to #status, notice: 'Status was successfully created.' }
format.json { render json: #status, status: :created, location: #status }
else
format.html { render action: "new" }
format.json { render json: #status.errors, status: :unprocessable_entity }
end
end
end
# PUT /statuses/1
# PUT /statuses/1.json
def update
#status = Status.find(params[:id])
respond_to do |format|
if #status.update_attributes(params[:status])
format.html { redirect_to #status, notice: 'Status was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #status.errors, status: :unprocessable_entity }
end
end
end
# DELETE /statuses/1
# DELETE /statuses/1.json
def destroy
#status = Status.find(params[:id])
#status.destroy
respond_to do |format|
format.html { redirect_to statuses_url }
format.json { head :no_content }
end
end
end
From looking at it, it seems you're wanting to append a user_name to a status
Error
Your error basically means you don't have a user_name column in your statuses data table. The basic fix will be to create a migration to add a user_name column to your statuses db:
$ rails generate migration AddUserNameToStatuses
#db/migrations/AddUserNameToStatuses.rb
class AddUserNameToStatuses < ActiveRecord::Migration
def change
add_column :statuses, :user_name, :string
end
end
$ rake db:migrate
Fix
I would actually ditch that, and do this:
#app/models/status.rb
Class Status < ActiveRecord::Base
belongs_to :user #-> you need user_id column in statuses db
delegate :name, to: :user, prefix: true
end
#app/models/user.rb
Class User < ActiveRecord::Base
has_many :statuses
end
This will allow you to remove the references to user_name from your form - as any #status will be associated with a user
You'd then be able to use the .delegate() method to call user_name in statuses

NoMethodError in Statuses#index

I get the following error when I try running my ruby on rails application:
NoMethodError in Statuses#index
undefined method `full_name' for #<Status:0x3fe0e38>
I don't understand why I am getting this error, I would appreciate if someone could point out where I've gone wrong!
Index.html.erb
<div class="page-header">
<h1>All Statuses</h1>
</div>
<%= link_to "Post A New Status", new_status_path, class: "btn btn-success" %>
<% #statuses.each do |status| %>
<div class="status">
<strong><%= status.full_name %></strong>
<p><%= status.content %></p></div>
<div class="meta">
<%= link_to time_ago_in_words(status.created_at) + " ago", status %>
<span class="admin">
| <%= link_to "Edit", edit_status_path(status) %> |
<%= link_to "Delete", status, method: :delete, data: { confirm: "Are you sure your want to delete this status?"} %>
</span>
</div>
</div>
<% end %>
User.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me,
:first_name, :last_name, :profile_name
# attr_accessible :title, :body
has_many :statuses
def full_name
first_name + " " + last_name
end
end
statuses_controller.rb
class StatusesController < ApplicationController
# GET /statuses
# GET /statuses.json
def index
#statuses = Status.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #statuses }
end
end
# GET /statuses/1
# GET /statuses/1.json
def show
#status = Status.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #status }
end
end
# GET /statuses/new
# GET /statuses/new.json
def new
#status = Status.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #status }
end
end
# GET /statuses/1/edit
def edit
#status = Status.find(params[:id])
end
# POST /statuses
# POST /statuses.json
def create
#status = Status.new(params[:status])
respond_to do |format|
if #status.save
format.html { redirect_to #status, notice: 'Status was successfully created.' }
format.json { render json: #status, status: :created, location: #status }
else
format.html { render action: "new" }
format.json { render json: #status.errors, status: :unprocessable_entity }
end
end
end
# PUT /statuses/1
# PUT /statuses/1.json
def update
#status = Status.find(params[:id])
respond_to do |format|
if #status.update_attributes(params[:status])
format.html { redirect_to #status, notice: 'Status was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #status.errors, status: :unprocessable_entity }
end
end
end
# DELETE /statuses/1
# DELETE /statuses/1.json
def destroy
#status = Status.find(params[:id])
#status.destroy
respond_to do |format|
format.html { redirect_to statuses_url }
format.json { head :no_content }
end
end
end
You are calling full_name on a status object, yet the method is defined in the user model. If you want the user's full name iterating through statuses you would do something like:
<%= status.user.full_name %>
assuming the association in Status exists for user
Because a Status does not have a full_name.
Your User model does, but you do not appear to be attempting to display a user, rather the statuses. It appears each user has unique statuses, so you could just print the status's user's full name.
That said, unless you really need arbitrary statuses per user, normally you might have a status table, and related users to statuses with a join table, which would make this technique unsuitable.
Really, you should be calling full_name on the User Object not the Status object.
<strong><%= status.user.full_name %></strong>
Assuming they both are associated (with a belongs_to :user), this should work.

undefined method `model_name' for NilClass:Clas

I am getting an error in Rails 3.2 with devise - my view is saying undefined method on line 1 below (user). This view is an edit profile page for logged in users.
So far I've tried changing this to current_user and defining that in my controller which I've provided below, but that did not work.
My only other suspicion is that form_for is not appropriate to use on this page?
<%= form_for(#user) do |f| %>
<% if #user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :username %><br>
<%= f.text_field :username %>
</div>
<div class="field">
<%= f.label :firstname %><br>
<%= f.text_field :firstname %>
</div>
<div class="field">
<%= f.label :lastname %><br>
<%= f.text_field :lastname %>
My controller... (as I said I tried current_user)
class UsersController < ApplicationController
def current_user
#current_user ||= User.find(session[:user_id])
end
def find
#user = User.new
end
def show
#user = User.find(params[:id])
end
# GET /users
# GET /users.json
def index
#users = User.all
end
# GET /users/1
# GET /users/1.json
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render action: 'show', status: :created, location: #user }
else
format.html { render action: 'new' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /users/1
# PATCH/PUT /users/1.json
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit(:username, :firstname, :dateofbirth, :lastname, :gender, :location, :email, :password)
end
end
Devise comes with a current_user helper method. You probably don't want to override that, so I'd recommend removing that method from your controller. In one of my apps I allow users to edit their info and this is my edit method:
def edit
#user = current_user
end

How to allow users to comment

So, I'd like users to be able to comment. At the present moment anyone can comment just by typing in a arbitrary name in the name field.
But I'd like to associate a comment with a user. So there will no longer be a need for a name field in the comments form as it will be the users name.
How can this be done?
I've followed Ryan Bates railscast but he never associates comments with users.
comments_controller.rb
class CommentsController < ApplicationController
before_action :set_comment, only: [:show, :edit, :update, :destroy]
def index
#comments = Comment.where("song_id IS NOT ?", nil)
end
def show
end
# GET /comments/new
def new
end
# GET /comments/1/edit
def edit
end
# POST /comments
# POST /comments.json
def create
#comment = Comment.new(comment_params)
respond_to do |format|
if #comment.save
format.html { redirect_to song_url(#comment.song_id), notice: 'Comment was successfully created.' }
format.json { render action: 'show', status: :created, location: #comment}
else
format.html { render action: 'new' }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /comments/1
# PATCH/PUT /comments/1.json
def update
respond_to do |format|
if #comment.update(comment_params)
format.html { redirect_to song_url(#comment.song_id), notice: 'Comment was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /comments/1
# DELETE /comments/1.json
def destroy
#comment.destroy
redirect_to song_url(#comment.song_id)
end
private
# Use callbacks to share common setup or constraints between actions.
def set_comment
#comment = Comment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def comment_params
params.require(:comment).permit(:song_id, :author_name, :site_url, :content, :user_id)
end
end
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :songs
has_many :comments
acts_as_voter
end
comment.rb
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :song
end
comments#form.html.erb
<%= form_for #comment do |f| %>
<% if #comment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#comment.errors.count, "error") %> prohibited this comment from being saved:</h2>
<ul>
<% #comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div id="comment_form">
<div class="field">
<%= f.hidden_field :song_id %>
<p>
<%= f.text_field :author_name, placeholder: "Name" %>
</p>
<p>
<%= f.text_area :content, :rows => '12', :cols => 35, placeholder: "Leave a comment..." %>
</p>
<p><%= f.submit "Submit" %></p>
<% end %>
<br /><br />
</div></div>
Your Comment table should have a column named user_id if it does not already. Then you can assign the user_id two different ways. These assume you have a current_user method. If you do not, then you will have to fill in the user_id from whatever session store or method you are using.
You could create a hidden_field in your form to assign it.
<%= f.hidden_field :user_id, value: current_user.id %>
but as noted by #rmagnum2002 this could be a security concern due to a user could edit this.
You could assign it during the create action:
def create
#comment = Comment.new(comment_params)
#comment.user_id = current_user.id
respond_to do |format|
if #comment.save
format.html { redirect_to song_url(#comment.song_id), notice: 'Comment was successfully created.' }
format.json { render action: 'show', status: :created, location: #comment}
else
format.html { render action: 'new' }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
Assigning this in the controller create action is probably best.

Resources