I have the models Post and Responce:
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :category
has_many :responces
end
class Responce < ActiveRecord::Base
belongs_to :user
belongs_to :post
default_scope -> { order('created_at DESC') }
end
I made feed by the example Ruby on Rails Tutorial
Michael Hartl
class ResponcesController < ApplicationController
def feed
Responce.where("post_id = ?", id)
end
def destroy
#responce.destroy
redirect_to post_path #post
end
end
In the view _feed_item
</span>
<% if feed_item.user %>
<%= link_to "delete", feed_item, method: :delete,
data: { confirm: "You sure?" },
title: feed_item.price %>
<% end %>
</li>
When I click <%= link_to "delete", feed_item, method: :delete, rails gives an error: undefined method 'responce' for #<Post
def destroy
#post.responce.destroy
end
What am I doing wrong?
Your responce association is a has_many, so Post has the method "responces" not "responce".
Related
In my Rails App, I have a comment model ,a devise user model and a tales model. For each tales post , I have comments posted by signed-in users.The problem here is every other logged in user is able to delete the comments of other user.I want a functionality such that only the user who created the comments can delete it.
My user.rb is here
class User < ActiveRecord::Base
has_one :profile, dependent: :destroy
has_many :tales, dependent: :destroy
end
My comment.rb is here
class Comment < ActiveRecord::Base
belongs_to :tale
end
My tale.rb is here
class Tale < ActiveRecord::Base
belongs_to :user
has_many :comments, dependent: :destroy
belongs_to :category
end
My routes.rb is as follows
Rails.application.routes.draw do
get 'tales/index'
devise_for :users, controllers: { registrations: "registrations" }
resources :profiles
resources :tales do
resources :comments
end
resources :categories
authenticated :user do
root "tales#index"
end
unauthenticated :user do
get "/" => "tales#index"
end
end
My comment controller is here:
class CommentsController < ApplicationController
before_action :authenticate_user!
def create
#tale = Tale.find(params[:tale_id])
#comment = #tale.comments.create(comment_params)
redirect_to tale_path(#tale)
end
def destroy
#tale = Tale.find(params[:tale_id])
#comment = #tale.comments.find(params[:id])
#comment.destroy
end
private
def comment_params
params.require(:comment).permit(:name, :body, :tale_id)
end
end
The excerpt from my tales/show page to add comments is here:
<div id="comments">
<h2><%= #tale.comments.count %> Comments</h2>
<%= render #tale.comments %>
<h3>Add a comment:</h3>
<%= render "comments/form" %>
</div>
</div>
My _comment.html.erb is here
<div class="comment clearfix">
<div class="comment_content">
<p class="comment_name"><strong><%= comment.name %></strong></p>
<p class="comment_body"><%= comment.body %></p>
<p class="comment_time"><%= time_ago_in_words(comment.created_at) %>
Ago</p>
</div>
<% if user_signed_in? %>
<p><%= link_to 'Delete', [comment.tale, comment], method: :delete, data:
{ confirm: 'Are you sure?' } %></p>
<% end %>
</div>
I see no connection between user and comments and I dont the right way to do it here.Can someone guide me through this such that I can do so without using any gems .
You don't appear to have a relationship between Comment and User. You would need something like this in your Comment class assuming you are storing the user_id for each comment:
belongs_to :user
Then in your CommentsController your destroy method should be something like this:
def destroy
# Only the comments posted by that user will be returned
#comment = #user.comments.find(params[:id])
#comment.destroy
end
Add use_id in comments table if don't have
add_column :comments, :user_id, :integer
in your view file put following condition. Delete link will only visible to user who added comment.
<% if user_signed_in? && current_user.id == comment.user_id %>
<p><%= link_to 'Delete', [comment.tale, comment], method: :delete, data:
{ confirm: 'Are you sure?' } %></p>
<% end %>
I am trying to build a simple learning app with rails 4.
here are my models:
class User < ActiveRecord::Base
has_many :enrollments
has_many :lectures, through: :enrollments
accepts_nested_attributes_for :enrollments
end
class Enrollment < ActiveRecord::Base
belongs_to :user
belongs_to :lecture
end
class Lecture < ActiveRecord::Base
has_many :enrollments
has_many :users, through: :enrollments
end
And here are my controllers
class EnrollmentsController < ApplicationController
before_action :authenticate_user!
def create
#enrollments = current_user.enrollments.build(enrollment_params)
if #enrollments.save
flash[:success] = "You have successfully enrolled."
redirect_to profile_path(current_user)
else
flash[:danger] = "Please try again."
redirect_to root_path
end
end
private
def enrollment_params
params.require(:enrollment).permit(:user_id, :lecture_id)
end
end
Here are my views:
lectures/index.html.erb
<% #lectures.each do |lecture| %>
<%= image_tag lecture.picture.url(:medium) %>
<p><%= truncate(lecture.description, length: 80) %> </p>
<%= link_to "Enroll Now", {:action=>"create", :controller=>"enrollments"}, :method => :post %>
<% end %>
The problem is that when you click on Enroll Now I have the following error:
ActionController::ParameterMissing in EnrollmentsController#create
param is missing or the value is empty: enrollment
def enrollment_params
params.require(:enrollment).permit(:user_id, :lecture_id)
end
How can i make it work? Need help please
In your lectures/index.html.erb file, you are not passing any data to the controller's action method.
<%= link_to "Enroll Now", {:action=>"create", :controller=>"enrollments"}, :method => :post %>
Might be better served with something a la
<%= link_to "Enroll Now", {:action=>"create", :controller=>"enrollments", :user_id => current_user.id**, :lecture_id => lecture.id}, :method => :post %>
# ** not sure how you snag the current user's id in your app but you'd need it.
Also, take a look at Routing in Rails. There are some super handy helper methods you can use that will allow you to do something like this (this was done quickly and may not be totally accurate but is offered to show you how you can use a route's path helper to clean up the code and make it even more readable):
<%= link_to 'Enroll Now', enrollments_path({enrollment: { user_id: current_user.id, lecture_id: lecture.id }}), :method => :post %>
class Question < ActiveRecord::Base
belongs_to :category
end
class Category < ActiveRecord::Base
has_many :questions
accepts_nested_attributes_for :questions, allow_destroy: true
end
CategoriesController:
private
def category_params
params.require(:category).permit(:title, questions_attributes: [:id, :category_id, :title, :_destroy])
end
In the view I have a category displaying all it's posts (CategoriesController#show).
Each post is deletable.
How could I construct a link_to helper that deletes a post by updating the category?
link_to "Remove question", category_path(category, question_attributes(id: question.id, _destroy: true)), method: :put
= link_to 'Delete question', question, method: :delete, data: {confirm: 'Are you sure?'}
and in routes.rb
resources :questions
and in your controller do what's necessary
class QuestionController < ApplicationController
def delete
question = Question.find(params[:id])
question.category = nil #or whatever you need to do
question.save
end
end
link_to "Remove question", category_path(category: { questions_attributes: {id: question.id, _destroy: true}}), method: :put
This will be best done using the .delete collection method in your controller:
#app/controllers/categories_controller.rb
def delete_question
#category = Category.find params[:category_id]
question = category.questions.find params[:id]
#category.questions.delete question
end
To get this working, you'll need to use the routes and link_to helper like this:
#config/routes.rb
resources :categories do
patch "question/:id", to: "categories#delete_question" #-> domain.com/categories/15/question/1
end
#app/views/categories/show.html.erb
<% #category.questions.each do |question| %>
<%= link_to "Remove Question", category_question_removal_path(category, question) method: :patch %>
<% end %>
I have two tables set up in a many to many relationship: maintenance_schedule and service_type. I'm trying to make a dropdown list on the form for maintenance_schedule that allows me to select service_type_name from the service_type table.
My models are set up like this:
class ServiceType < ActiveRecord::Base
attr_accessible :service_type_name
has_many :maintenance_schedules, :through => :schedule_services
end
class MaintenanceSchedule < ActiveRecord::Base
attr_accessible :maintenance_schedule_date
has_many :service_types, :through => :schedule_services
accepts_nested_attributes_for :service_types
end
class ScheduleService < ActiveRecord::Base
attr_accessible :maintenance_schedule_id, :service_type_id
belongs_to :maintenance_schedule
belongs_to :service_type
end
my index page is giving me undefined method `service_type_name'
<p id=<%="maintenance_schedule_#{maintenance_schedule.id}"%>>
<div>service type: <%= maintenance_schedule.service_types.service_type_name %></div>
<%= link_to "Delete", maintenance_schedule_path(maintenance_schedule.id), :method => :delete, :class => "delete", :confirm => "Are you so sure?"%>
<%= link_to "Edit", edit_maintenance_schedule_path(maintenance_schedule)%>
This is my index method in the controller
def index
#maintenance_schedules = MaintenanceSchedule.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #maintenance_schedules}
end
end
Im trying to add a destroy button on my nested resource and getting this error: No route matches [DELETE] "/users/1/2/4/5/holidays/7"
Heres the relevant parts of my view,routes, models, & controllers:
<% #user.holidays.each do |h| %>
<td><%= h.name %></td>
<td><%= h.date %></td>
<td>
<%= button_to('Destroy', user_holiday_path(#user.holidays), :method => 'delete', :class => 'btn btn-large btn-primary') %>
</td>
<% end %>
Routes
resources :users do
resources :interests
resources :holidays
end
Models
class User < ActiveRecord::Base
has_many :holidays, :through => :user_holidays
end
class UserHoliday < ActiveRecord::Base
attr_accessible :holiday_id, :user_id
belongs_to :user
belongs_to :holiday
end
class Holiday < ActiveRecord::Base
attr_accessible :name, :date
has_many :user_holidays
has_many :users, :through => :user_holidays
end
Controller
class HolidaysController < ApplicationController
def index
#user_holidays = Holiday.find(params[:user_id])
#holidays = #user_holidays.holidays
end
def new
end
def show
#holiday = Holiday.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #holiday }
end
end
def destroy
#holiday = Holiday.find(params[:id])
#holiday.destroy
end
end
Thanks!!!
Change this :
<%= button_to('Destroy', user_holiday_path(#user.holidays), :method => 'delete', :class => 'btn btn-large btn-primary') %>
to this:
<%= button_to('Destroy', user_holiday_path(h), :method => 'delete', :class => 'btn btn-large btn-primary') %>
Update
Change your destroy action from :
#holiday = Holiday.find(params[:id]) to
#user_holiday = UserHoliday.find(params[:id])
and in your view:
change
<% #user.holidays.each do |h| %>
to
<% #user.user_holidays.each do |h| %>
Your associations need some correction and should be as follows:
user has_many user_holidays
user_holiday has_one holiday
user_holidays belongs_to user
You can access name and holiday via your h object:
h.holiday.name
h.holiday.date