Comments on Posts in Rails - html

So I am trying to build a comments feature for my posts in a rails project but having troble figuring out the views and the controllers on being able to successfully make a comment on a post. The way I have it is that I have a link on each post in my news feed named comments that redirects you to a show page that shows a single post. on that page I would like to have a form just like my post form in the home page, but this one would be for comments on posts, any help figuring out the controllers, form for comments, and making them display under the post in the post show page would be much appreciated
here is the controller and view template for the Post controller
class PostsController < ApplicationController
before_action :logged_in_user, only: [:show, :create, :destroy]
before_action :correct_user, only: :destroy
def show
#post = Post.find(params[:id])
end
def create
#post = current_user.posts.build(post_params)
if #post.save
redirect_to root_url
else
#feed_items = []
render 'static_pages/home'
end
end
def destroy
redirect_to request.referrer || root_url
end
private
def post_params
params.require(:post).permit(:content, :picture)
end
def correct_user
#post = current_user.posts.find_by(id: params[:id])
redirect_to root_url if #post.nil?
end
end
the post show page
<% if logged_in? %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<%= render 'shared/user_info' %>
</section>
</aside>
<div class="col-md-8 posts">
<h3>Comments</h3>
<%= render 'posts/post_show' %>
</div>
</div>
<% end %>
My comments controller so far
class CommentsController < ApplicationController
before_action :loged_in_user, only:[:create, :destroy]
before_action :correct_user, only: :destroy
def create
#post = Post.find(params[:id])
#comment = Comment.new(params[:comment])
#comment.post = #post
#comment.user = current_user
if #comment.save
redirect_to post
else
render 'post/show'
end
end
def destroy
end
private
def comment_params
params.require(:comment).permit(:content, :picture)
end
def correct_user
#comment = current_user.comment.find_by(id: params[:id])
render 'post/show' if #comment.nil?
end
end
How my post partial is rendered would like to render comments the same way under the post in the post show page
<li id="post-<%= post.id %>">
<%= link_to gravatar_for(post.user), post.user %>
<span class="user"><%= link_to post.user.name, post.user %></span>
<span class="content"><%= post.content %></span>
<%= image_tag post.picture.url if post.picture? %>
<span class="timestamp">
Posted <%= time_ago_in_words(post.created_at) %> ago.
<%= link_to "comments", post %>
<% if current_user?(post.user) %>
<%= link_to "delete", post, method: :delete, data: { confirm: "You sure?" } %>
<% end %>
</span>
</li>
my post model
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments, dependent: :destroy
default_scope -> { order(created_at: :desc) }
mount_uploader :picture, PictureUploader
validates :user_id, presence: true
validates :content, presence: true, length: { maximum: 500 }
validate :picture_size
private
def picture_size
if picture.size > 10.megabytes
errors.add(:picture, "should be less than 10MB")
end
end
end
and comments model
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :post
default_scope -> { order(created_at )}
validates :user_id , pressence: true
validates :post_id , pressence: true
validates :content, presence: true, length: { maximum: 500 }
validate :picture_size
private
def picture_size
if picture.size > 5.megabytes
errors.add(:picture, "should be less than 5MB")
end
end
end
and this is my user model
class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
has_many :comments, dependent: :destroy
attr_accessor :remember_token, :activation_token, :reset_token
before_save :downcase_email
before_create :create_activation_digest
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 250 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false}
has_secure_password
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
def User.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
# Returns a random token.
def User.new_token
SecureRandom.urlsafe_base64
end
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
def forget
update_attribute(:remember_digest, nil)
end
def activate
update_attribute(:activated, true)
update_attribute(:activated_at, Time.zone.now)
end
# Sends activation email.
def send_activation_email
UserMailer.account_activation(self).deliver_now
end
# Sets the password reset attributes.
def create_reset_digest
self.reset_token = User.new_token
update_attribute(:reset_digest, User.digest(reset_token))
update_attribute(:reset_sent_at, Time.zone.now)
end
# Sends password reset email.
def send_password_reset_email
UserMailer.password_reset(self).deliver_now
end
def password_reset_expired?
reset_sent_at < 2.hours.ago
end
def feed
Post.where("user_id = ?", id)
end
private
def downcase_email
self.email = email.downcase
end
def create_activation_digest
self.activation_token = User.new_token
self.activation_digest = User.digest(activation_token)
end
end
routes file
Rails.application.routes.draw do
get 'password_resets/new'
get 'password_resets/edit'
root 'static_pages#home'
get 'help' => 'static_pages#help'
get 'about' => 'static_pages#about'
get 'contact' => 'static_pages#contact'
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
resources :users
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :posts, only: [:show, :create, :destroy]
resources :comments, only: [:show, :create, :destroy]
end

You can start from your route file. First of all, you need to define route for comments that belong to a post.
Here's how:
resources :posts do
resources :comments
end
This way, you can edit a comment that belongs to a particular post like /posts/3/comments/2. This path will take you to the comment with id 2 that belongs to a post whose id is 3.
You also need to re-define all the methods in CommentsController. For example,
def update
#post = Post.find(params[:id])
#comment = Comment.find(params[:comment_id])
...
end
Well, that was just a sneak-peak of what you are supposed to do. It would be very lengthy indeed to show all the procedure here. Check out this to further have an idea of how it all fits.

Related

What's wrong with my form in Ruby on Rails?

I'm trying to implement a prayer request and prayer response form, much like a micropost with a comment on it. The prayer requests are created and deleted as expected, but when I try to post a prayer response, it just reloads the page with no errors and no flash saying that the post was successful. This behavior happens wether the post is valid or not (no errors for a blank response, just a reload of the page) When I use the rails console, I'm able to build and save a prayer response successfully, and it shows up on rails server. What's wrong with my form? Based on the server log, I see that when I try to post a prayer response, it's using the RequestsController instead of the PrayerResponsesController. How do I fix this?
Here's my server log errors:
Started POST "/requests" for 127.0.0.1 at 2023-01-18 16:24:36 -0600
Processing by RequestsController#create as TURBO_STREAM
Parameters: {"authenticity_token"=>"[FILTERED]", "content"=>"Prayer response...", "request_id"=>"150", "commit"=>"Respond in Prayer"}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/helpers/sessions_helper.rb:18:in `current_user'
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/helpers/sessions_helper.rb:18:in `current_user'
Completed 400 Bad Request in 4ms (ActiveRecord: 0.1ms | Allocations: 2115)
ActionController::ParameterMissing (param is missing or the value is empty: request
Did you mean? request_id):
Here's my code:
controllers/prayer_responses_controller.rb
class PrayerResponsesController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
before_action :correct_user, only: :destroy
def create
#prayer_response = current_user.prayer_responses.build(prayer_response_params)
if #prayer_response.save
flash[:success] = "Prayer Response created!"
redirect_back(fallback_location: root_url)
else
render 'static_pages/requests', status: :unprocessable_entity
end
end
def destroy
#prayer_response.destroy
flash[:success] = "Prayer Response deleted"
redirect_back_or_to( root_url, status: :see_other )
end
private
def prayer_response_params
params.require(:prayer_response).permit(:content, :request_id)
end
def correct_user
#prayer_response = current_user.prayer_responses.find_by(id: params[:id])
redirect_to root_url, status: :see_other if #prayer_response.nil?
end
end
views/static_pages/requests.html.erb
<% provide(:title, "Prayer Requests") %>
<div class="row">
<aside class="col-md-4">
<section class="request-form">
<%= render 'shared/request_form' %>
</section>
</aside>
<div class="col-md-8">
<h3>Prayer Requests</h3>
<% if Request.all != nil %>
<%= render Request.all %>
<% end %>
</div>
</div>
views/requests/_request.html.erb
<li id="request-<%= request.id %>" class="requests">
<%= link_to gravatar_for(request.user, size: 50), request.user %>
<span class="user"><%= link_to request.user.name, request.user %></span>
<span class="content"><%= request.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(request.created_at) %> ago.
<% if current_user?(request.user) %>
<%= link_to "delete", request, data: { "turbo-method": :delete,
"turbo-confirm": "Are you sure?"} %>
<% end %>
</span>
<% if current_user != nil %>
<span>
<%= render 'shared/prayer_response_form', request_id: request.id %>
</span>
<span>
<% if request.prayer_responses.any? %>
<ol class="prayer_responses">
<% request.prayer_responses.reverse.each do |prayer_response| %>
<%= render prayer_response %>
<% end %>
</ol>
<% end %>
</span>
<% end %>
</li>
views/prayer_responses/_prayer_response.html.erb
<li id="prayer_response-<%= prayer_response.id %>">
<%= link_to gravatar_for(prayer_response.user, size: 30), prayer_response.user %>
<span class="user"><%= link_to prayer_response.user.name, prayer_response.user %></span>
<span class="content"><%= prayer_response.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(prayer_response.created_at) %> ago.
<% if current_user?(prayer_response.user) %>
<%= link_to "delete response", prayer_response, data: { "turbo-method": :delete,
"turbo-confirm": "Are you sure?"} %>
<% end %>
</span>
</li>
views/shared/_prayer_response_form.html.erb
<%= form_with(model: #prayer_response) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<center>
<div class="field">
<%= f.text_area(:content, placeholder: "Respond to this prayer request...") %>
</div>
<div><%= f.hidden_field :request_id, value: request_id %></div>
<%= f.submit "Respond in Prayer", class: "btn btn-primary" %>
</center>
<% end %>
models/prayer_response.rb
class PrayerResponse < ApplicationRecord
belongs_to :user
belongs_to :request
default_scope -> { order( created_at: :desc) }
validates :user_id, presence: true
validates :request_id, presence: true
validates :content, presence: true, length: { maximum: 500 }
end
models/request.rb
class Request < ApplicationRecord
belongs_to :user
has_many :prayer_responses, dependent: :destroy
default_scope -> { order(created_at: :desc) }
validates :user_id, presence: true
validates :content, presence: true, length: { maximum: 280 }
end
db/migrate/20230113172701_create_prayer_responses.rb
class CreatePrayerResponses < ActiveRecord::Migration[7.0]
def change
create_table :prayer_responses do |t|
t.text :content
t.references :user, null: false, foreign_key: true
t.references :request, null: false, foreign_key: true
t.timestamps
end
add_index :prayer_responses, [:user_id, :request_id, :created_at]
end
end
db/migrate/20230107204925_create_requests.rb
class CreateRequests < ActiveRecord::Migration[7.0]
def change
create_table :requests do |t|
t.text :content
t.references :user, null: false, foreign_key: true
t.timestamps
end
add_index :requests, [:user_id, :created_at]
end
end
config/routes.rb
root "static_pages#home"
get "/help", to: "static_pages#help"
get "/about", to: "static_pages#about"
get "/contact", to: "static_pages#contact"
get "/new_public_prayers", to: "static_pages#new_public_prayers"
get "/signup", to: "users#new"
get "/login", to: "sessions#new"
post "/login", to: "sessions#create"
delete "/logout", to: "sessions#destroy"
resources :users do
member do
get :following, :followers
end
end
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :prayers, only: [:create, :destroy]
resources :requests, only: [:create, :destroy]
resources :prayer_responses, only: [:create, :destroy]
resources :comments, only: [:create, :destroy]
resources :private_prayers, only: [:create, :destroy]
resources :relationships, only: [:create, :destroy]
get "/private_prayers", to: "static_pages#private_prayers"
get "/prayers", to: "static_pages#home"
get "/comments", to: "static_pages#home"
get "/requests", to: "static_pages#requests"
get "/prayer_responses", to: "static_pages#requests"
end
The answer, actually, was in the static_pages_controller.rb file... I needed to add #prayer_response = current_user.prayer_responses.build to the requests page's function...
class StaticPagesController < ApplicationController
def home
if logged_in?
#prayer = current_user.prayers.build
#comment = current_user.comments.build
#feed_items = current_user.feed.paginate(page: params[:page])
end
end
def help
end
def about
end
def contact
end
def new_public_prayers
end
def private_prayers
if logged_in?
#private_prayer = current_user.private_prayers.build
else
redirect_to root_url
end
end
def requests
if logged_in?
#request = current_user.requests.build
#prayer_response = current_user.prayer_responses.build
else
redirect_to root_url
end
end
end
This made sure that the proper controller was followed when building a new prayer response, etc.

How to show all the Users who have liked my post

I apologize for the newbie questions still relatively new to rails. I'm trying to show all the users who have liked my specific posts. I took a look at this similar question How to list the users who LIKE a given Post but it couldn't solve my problem. I listed below all the relevant simple code - thank you so much guys!!
Items Controller
class ItemsController < ApplicationController
before_action :authenticate_user!, only: [:new, :create]
before_action :set_item, only: [:show, :edit, :update, :destroy, :share]
def index
#items = Item.order("created_at DESC")
end
end
Index.html.erb
<% if user_signed_in? %>
<%= image_tag current_user.avatar, width: 70, class: "css-style" %>
<br>
<strong><%= link_to current_user.username, current_user, class: "profile-style" %></strong>
<ul><!--Trying to show all the users who have liked my specific posts here -->
<% item.likes.each do |like| %>
<li> <%= link_to(like.user.username, like.user) %></li>
<% end %>
</ul>
<br>
<br>
<% else %>
<%= link_to 'Login/SignUp', new_user_session_path %>
<% end %>
<% #items.each do |item| %>
<%= image_tag item.avatar.url(:medium), class: "block" %>
<div>
<%= render partial: "likes", locals: {item: item} %></span><%= item.likes_count %>
</div>
<% end %>
Items.rb
class Item < ApplicationRecord
has_many :likes, :counter_cache => true
belongs_to :user
has_attached_file :avatar, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\z/
end
User.rb
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable, omniauth_providers: [:facebook]
has_many :likes
has_attached_file :avatar, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\z/
def likes?(post)
post.likes.where(user_id: id).any?
end
end
Users Controller
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy, :share]
def index
#users = User.all
end
def show
#user = User.find(params[:id])
#items = Item.all
end
private
def set_user
#user = User.find(params[:id])
end
def item_params
params.require(:item).permit(:product, :amount, :city_id, :avatar)
end
end
Like.rb
class Like < ApplicationRecord
belongs_to :item, :counter_cache => true
belongs_to :user
end
Likes Controller
class Items::LikesController < ApplicationController
before_action :authenticate_user!
before_action :set_book
def create
#item.likes.where(user_id: current_user.id).first_or_create
respond_to do |format|
format.html {redirect_to #item}
format.js
end
end
def destroy
#item.likes.where(user_id: current_user.id).destroy_all
respond_to do |format|
format.html {redirect_to #item}
format.js
end
end
private
def set_book
#item = Item.find(params[:item_id])
end
end
Logs
Processing by ItemsController#index as HTML
Rendering items/index.html.erb within layouts/application
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
Item Load (0.3ms) SELECT "items".* FROM "items" ORDER BY created_at DESC
Rendered items/index.html.erb within layouts/application (287.6ms)
Completed 500 Internal Server Error in 313ms (ActiveRecord: 0.6ms)
ActionView::Template::Error (undefined local variable or method `item' for #<#:0x007f9afbfd14f0>
Did you mean? item_url
items_url
item_path
#items):
5:
6: <%= link_to current_user.username, current_user, class: "profile-style" %>
7:
8: <% item.likes.each do |like| %>
9: <%= link_to(like.user.username, like.user) %>
10: <% end %>
11:
app/views/items/index.html.erb:8:in `_app_views_items_index_html_erb___2312434021832006771_70151814680620'
Rendering /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout
Rendering /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
Rendered /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (8.3ms)
Rendering /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
Rendered /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (3.3ms)
Rendering /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
Rendered /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.2ms)
Rendered /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout (94.4ms)
In items/index.html.erb you are referencing #item.likes.each on line 9, but the instance variable #item has not been set in items_controller#index. You have only defined #items, hence the error you are receiving about nil not responding to #likes.
If you want to see the likes for all items, there are a number of ways to achieve this with Arel.
It's a simple mistake. I think the problem is with your partial.. you're calling the partial with locals and inside your template code you are referring to it with #item instead of item, here item is not an instance variable.
<% #items.each do |item| %>
<%= image_tag item.avatar.url(:medium), class: "block" %>
<div>
<%= render partial: "likes", locals: {item: item} %></span><%= item.likes_count %>
</div>
<% end %>
The thing is when you render a partial with locals you need to use the locals as normal variables not as instance variables.
This should work.
<% item.likes.each do |like| %>
<li> <%= link_to(like.user.username, like.user) %></li>
<% end %>
You need one more table(model) "likes" and association has-many-through. Something like this:
class Item
has_many :likes
has_many :users, through: :likes
end
class Like
belongs_to :user
belongs_to :item
end
class User
has_many :likes
has_many :items
has_many :liked_items, through: :likes
end

How to set up a Count from my Controller in Rails

I'm new to ruby on rails so please forgive the question. I tried following this example How to "count" user inputs from a Controller but kept getting nothing in my view. I am trying to create a count functionality on my share feature (similar to retweet which works perfectly now). >> So whenever a user shares a tweet there is a counter that changes with it as well. I have listed below all my relevant code. Thank you so much guys!!
tweets_controller.rb
class TweetsController < ApplicationController
before_action :set_tweet, only: [:show, :edit, :update, :destroy, :share]
def index
#tweets = Tweet.all
end
def share
tweet = current_user.tweets.create(tweet_id: #tweet.id)
if tweet.save
redirect_to tweets_path
else
redirect_to :back, alert: "Unable to share"
end
end
_share.html.erb
<div>
<div>Shared by <%= tweet.user.username %></div>
<%= render partial: "tweets/tweet", locals: {tweet: tweet.tweet} %>
</div>
_tweet.html.erb
<div class="row">
<div class="col-md-3"><%= tweet.watches_count %><%= render partial: "watches", locals: {tweet: tweet} %></div>
<div class="col-md-3"><%= link_to '<i class="fa fa-share fa-lg" aria-hidden="true"></i>'.html_safe, share_tweet_path(tweet), method: :post %></div>
<div class="col-md-6"><span class="pull-right"><%= tweet.likes_count %><%= render partial: "likes", locals: {tweet: tweet} %></span></div>
</div>
</div>
routes.rb
Rails.application.routes.draw do
resources :tweets do
resource :like, module: :tweets
resource :watch, module: :tweets
member do
post :share
end
end
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
resources :users, :controllers => "users_controller.rb"
root to: "tweets#index"
end
Migration CreateTweets
class CreateTweets < ActiveRecord::Migration[5.0]
def change
create_table :tweets do |t|
t.text :body
t.integer :user_id
t.integer :tweet_id
t.timestamps
end
end
end
Relevant Rake Routes
share_tweet POST /tweets/:id/share(.:format) tweets#share
tweets GET /tweets(.:format) tweets#index
POST /tweets(.:format) tweets#create

undefined method `cliq_requests' for nil:NilClass

I keep getting this annoying error consistently and I cannot solve it. I recently posted a question on the same topic and got no productive help.
I want users to request to join a group. Cliqs = Groups. All of my console tests seem correct, but I cannot seem to find a solution to my problem. The association is showing up, but I can't seem to get the update/accept method to run.
This is driving me crazy! How do I fix this?
Here is my code:
My Models:
class User < ActiveRecord::Base
has_many :uploads
has_one :owned_cliq, foreign_key: 'owner_id', class_name: 'Cliq', dependent: :destroy
has_many :cliq_memberships, dependent: :destroy
has_many :cliqs, through: :cliq_memberships
has_many :cliq_requests, dependent: :destroy
...
end
class Cliq < ActiveRecord::Base
belongs_to :owner, class_name: 'User'
has_many :cliq_memberships, dependent: :destroy
has_many :members, through: :cliq_memberships, source: :user
has_many :cliq_requests, dependent: :destroy #cliq_request_sender
has_many :pending_members, through: :cliq_requests, source: :user, foreign_key: 'user_id'
end
class CliqRequest < ActiveRecord::Base
#from
belongs_to :user
#to
belongs_to :cliq
#validate :not_member
#validate :not_pending
def accept
cliq.members << pending_member
destroy
end
end
My controller:
class CliqRequestsController < ApplicationController
def index
#incoming
##cliq_requests_received = CliqRequest.where(cliq: cliq)
#outgoing
##cliq_requests_sent = current_user.cliq_requests
end
def show
end
def create
cliq = Cliq.find_by(params[:id])
#cliq_request = current_user.cliq_requests.new(cliq: cliq)
if #cliq_request.save
redirect_to current_user #change to cliqs/cliq path later
else
redirect_to cliq_path
end
end
def update
#cliq = Cliq.find_by(id: params[:cliq_id])
#cliq_request = #cliq.cliq_requests.find_by(id: params[:id])
#cliq_request.accept
end
def destroy
#cliq_request.destroy
end
end
My View:
<h1><%= #cliq.name %></h1>
<%= link_to 'Request to join Cliq', '/cliqs/:cliq_id/cliq_requests', :method => :post %>
<% #cliq_members.each do |cliq_member| %>
<ul><%= link_to cliq_member.username, user_path(cliq_member) %></ul>
<% end %>
<% if #current_user = #cliq.owner %>
<% #cliq.pending_members.each do |pending_member| %>
<ul><%= link_to pending_member.username, user_path %>
<%= link_to "Accept", "/cliqs/:cliq_id/cliq_requests/:id/", :method => :put %>
<%= link_to "Deny", "/cliqs/:cliq_id/cliq_requests/:id/", :method => :delete %>
</ul>
<% end %>
<% end %>
My Routes:
resources :cliqs do
resources :cliq_requests
end
These lines appear malformed:
<%= link_to 'Request to join Cliq', '/cliqs/:cliq_id/cliq_requests', :method => :post %>
<%= link_to "Accept", "/cliqs/:cliq_id/cliq_requests/:id/", :method => :put %>
<%= link_to "Deny", "/cliqs/:cliq_id/cliq_requests/:id/", :method => :delete %>
I recommend you use path helpers [e.g. cliq_cliq_request_path(cliq, cliq_request) if you are using resourceful routing]. You can use rake routes for help. If you are seeing things like :cliq_id and and :id in your development.log or test.log as part of the URLs that are hit, those should instead be numbers. You can also interpolate the strings yourself (e.g. "/cliqs/#{cliq_id}/cliq_requests/#{cliq_request.id}") but this is usually more typing and certainly more fragile over time.
One of your problems may be that you are looping through a list of pending member names, which doesn't have all the data you need to form the link correctly. So your update action may be working fine, but you may not be passing it the right data.
Also this line:
if #current_user = #cliq.owner
is an assignment, and so will always return true. Presumably you mean ==

Setting up associations and forms for my Quora Like Rails App

Hello I am trying to build a quora like app using ruby on rails. I have decided to call my questions pins in this case, and my answers are still answers. However When I try to answer a question I get this error:
NameError at /pins/2 undefined local variable or method `answer' for #<#<Class:0x007fc934792fc0>:0x007fc93428fb18>
I am using Devise as well. Here is my associations thus far.
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 :pins
has_many :answers
has_attached_file :image, :styles => { :medium => "400x400", :thumb => "200x200" }, : :default_url => "avatar/missing.jpg"
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
end
Here is my Pin Model
class Pin < ActiveRecord::Base
belongs_to :user
validates :description, presence: true
has_many :answers
end
Here is my Answer Model
class Answer < ActiveRecord::Base
belongs_to :pin
belongs_to :user
validates :description, presence: true
end
Here is my Pins Controller
class PinsController < ApplicationController
before_action :set_pin, only: [:show, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
#pins = Pin.all.order("created_at DESC").paginate(:page => params[:page], :per_page => 50)
end
def show
end
def new
#pin = current_user.pins.build
end
def edit
end
def create
#pin = current_user.pins.build(pin_params)
if #pin.save
redirect_to #pin, notice: 'Pin was successfully created.'
else
render action: 'new'
end
end
def update
if #pin.update(pin_params)
redirect_to #pin, notice: 'Pin was successfully updated.'
else
render action: 'edit'
end
end
def destroy
#pin.destroy
redirect_to pins_url
end
private
# Use callbacks to share common setup or constraints between actions.
def set_pin
#pin = Pin.find(params[:id])
end
def correct_user
#pin = current_user.pins.find_by(id: params[:id])
redirect_to pins_path, notice: "Not authorized to edit this pin" if #pin.nil?
end
# Never trust parameters from the scary internet, only allow the white list through.
def pin_params
params.require(:pin).permit(:description)
end
end
and Here is my Answer Controller
class AnswersController < ApplicationController
before_action :set_answer, only: [:show, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def create
#pin = Pin.find(params[:pin_id])
#answer = #pin.answers.create(answer_params)
redirect_to pin_path(#pin)
end
private
def set_answer
#answer = Answer.find(params[:id])
end
def correct_user
#answer = current_user.answers.find_by(id: params[:id])
redirect_to answers_path, notice: "Not authorized to edit this pin" if #answer.nil?
end
def answer_params
params.require(:answer).permit(:description)
end
end
And Here is my show form
<%= render 'layouts/header' %>
<%= notice %>
<p>
<strong>Description:</strong>
<%= #pin.description %>
</p>
<h2>Answers</h2>
<% #pin.answers.each do |comment| %>
<p>
<strong>Answer:</strong>
<%= answer.description %>
</p>
<% end %>
<h2>Answer this questions:</h2>
<%= form_for([#pin, #pin.answers.build]) do |f| %>
<p>
<%= f.label :description %><br>
<%= f.text_field :description %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Edit', edit_pin_path(#pin) %> |
<%= link_to 'Back', pins_path %>
Could anyone tell me the problem. Thanks in an advance.
You have a mistake in view:
<% #pin.answers.each do |comment| %> # Here you have "comment"
<p>
<strong>Answer:</strong>
<%= answer.description %> # And here "answer", change it to "comment" or vice versa
</p>
<% end %>