I have A comments Controller Where a User can go tip the comment (right now clicking it will flash a sentence, will add functions later). The problem I'm having is that the page is loading but when I click the link nothing is happening. I'm getting this error when I go to the console:
AbstractController::ActionNotFound - The action 'tip' could not be found for CommentsController
But I have the action in our controller here:
def tip
redirect_to :back, :notice => "Thank you for the Tip. The User will Love it"
end
Here's the route for the tip:
get "/:id/tip" => "comments#tip", :as => "tip"
Here's the Link_to also"
= link_to(tip_path(comment), :class => "story-likes-link", :remote => true, :title => "Tip comment" ) do
%i.fa.fa-money.fa-lg
Tip
Thank you so much for the help : )
edit: whole Controller
class CommentsController < ApplicationController
before_action :authenticate_user!
before_action :set_user
before_action :set_resource, :except => [:destroy]
before_action :set_parent, :except => [:destroy]
before_action :set_comment, :only => [:update, :destroy]
respond_to :js
# Create the comments/replies for the books/comics
def create
#comment = current_user.comments.new(comment_params)
if #comment.save
#comment.move_to_child_of(#parent) unless #parent.nil?
end
respond_with #comment, #resource
end
# Update the comments for the user
def update
#comment.update_attributes(comment_params)
respond_with #comment, #resource
end
# Delete the comments for the books/comics
def destroy
#resource = #comment.commentable
#comment.destroy
respond_with #resource
end
private
# Permitted parameters
def comment_params
params.require(:comment).permit(:body, :commentable_id, :commentable_type, :parent_id)
end
# Set the parent resource for the comments and replies
def set_resource
if params[:comment][:commentable_type].eql?("Book")
#resource = Book.find(params[:comment][:commentable_id])
else
#resource = Comic.find(params[:comment][:commentable_id])
end
end
# Set the parent for the comments to make then as the child of the parent
def set_parent
#parent = params[:comment].has_key?(:parent_id) ? Comment.find(params[:comment][:parent_id]) : nil
end
# Set the comment for the source
def set_comment
#comment = Comment.find(params[:id])
end
def tip
redirect_to :back, :notice => "Thank you for the Tip. The User will Love it"
end
def set_user
#user = User.find(params[:user_id])
end
end
The problem is the action #tip method is hidden in private section, so the router sees not the method at all.
Well, then move the method's code above the private keyword:
def tip
redirect_to :back, :notice => "Thank you for the Tip. The User will Love it"
end
private
NOTE: that action method should not be place to private or protected sections, only to public, which is default section for ruby class definition flow.
Related
I have a resumes controller and a welcomes controller in my app. The welcomes controller has only an index action which is there for the root page. The purpose of the resumes controller is to upload(new/create), download(download) etc. pdf files as an logged in user and it works great so far.
I want to implement the resume download feature on the rootpage as well.(welcomes_controller /index).
How can I accomplish this?
Since I can not call the variable to access the resume model from the welcomes controller. How should the routes be? What should I modify on the welcomes_controller?
routes.rb
Rails.application.routes.draw do
devise_for :users
root 'welcomes#index'
resources :resumes do
get :download, on: :member
end
get '*path' => redirect('/')
end
resumes_controller.rb
class ResumesController < ApplicationController
around_filter :catch_not_found
before_action :find_resume, only: [ :show, :edit, :update, :destroy, :download ]
before_action :authenticate_user!
def show
end
def new
if #resume = current_user.resume
redirect_to #resume
else
#resume = Resume.new
end
end
def create
#resume = current_user.build_resume(resume_params)
if #resume.save
redirect_to #resume
else
render :new
end
end
def edit
end
def update
if #resume.update resume_params
redirect_to #resume, notice: "Your resume was successfully saved!"
else
render 'edit'
end
end
def destroy
#resume.destroy
redirect_to new_resume_path, notice: "Your resume was successfully deleted!"
end
def download
send_data #resume, type: "application/pdf", disposition: "attachment"
end
private
def resume_params
params.require(:resume).permit( :user_id, :download_file, :remove_download_file)
end
def find_resume
#resume = Resume.find(params[:id])
end
def catch_not_found
yield
rescue ActiveRecord::RecordNotFound
redirect_to(root_url, :notice => 'Record not found')
end
end
resumes/show.html.erb
...
...
<%= link_to "Download", download_resume_path(#resume), "data-turbolinks" => false %>
welcomes_controller.rb
class WelcomesController < ApplicationController
def index
end
end
you can access Resume model from welcome controller, although controller is welcome you can call Resume model see sample below
class WelcomesController < ApplicationController
def index
# you can call Resume model frome here
#resumes = Resume.all
end
def show
#resume = Resume.find(params[:id])
end
end
I am building a fairly straightforward Rails 5 application. You create "Movies," and then can create "Reviews" for those movies. Rails is doing something odd. I have my application set up so instead of a "new" action and a corresponding view, I have the form to create new movies in a modal contained in the application.html.erb file. I then provide #newmovie = Movie.new in the controller for all the movie views, so the data is available everywhere.
I have validations for the movie object setup like this:
class Movie < ApplicationRecord
has_many :reviews
validates :title, :director, :poster, :synopsis, presence: true
end
When I fill out the form to create a new movie in the modal on my index view and intentionally leave fields blank (to trigger the validation), I get this:
instead of the form simply not accepting the input. What's going on here? I can't have this error happening like this. Previously, I had a "new" view. This did not happen in the previous setup. Help!
Here is my entire movies controller:
class MoviesController < ApplicationController
before_action :find_movie, only: [:show, :edit, :update, :destroy ]
before_action :authenticate_user!, only: [:new, :create, :edit, :update, :destroy]
before_action :find_newmovie, only: [:show, :index, :new, :edit]
def show
#reviews = #movie.reviews.all.order(created_at: :desc).paginate(:page => params[:page], :per_page => 3)
#review = Review.new
if #movie.reviews.blank?
#average_review = 0
else
#average_review = #movie.reviews.average(:rating).round(2)
end
end
def index
#movies = Movie.all.order(title: :asc).paginate(:page => params[:page], :per_page => 3)
#newmovie = Movie.new
end
def new
#movie = Movie.new
end
def create
#movie = Movie.create(movie_params)
#movie.user_id = current_user.id
if #movie.save
flash[:success] = "Your movie was created!"
redirect_to root_path
else
flash[:danger] = "There was a problem with your request"
render :new
end
end
def edit
end
def update
if #movie.update(movie_params)
flash[:success] = "Your movie was updated"
redirect_to movie_path
else
flash[:danger] = "There was a problem with your request"
end
end
def destroy
if #movie.destroy
flash[:success] = "Your movie was removed"
redirect_to movies_path
else
flash[:danger] = "There was a problem with your request"
render :index
end
end
private
def movie_params
params.require(:movie).permit(:title, :director, :poster, :synopsis, :user_id)
end
def find_movie
#movie = Movie.find(params[:id])
end
def find_newmovie
#newmovie = Movie.new
end
end
In new action of movies_controller, you missed to initalize the instance variable #newmovie.
add below code in movies_controller:
class MoviesController < ApplicationController
def new
#newmovie = Movie.new
end
...
end
i don't know what's wrong, I tried to add "create" method to my application, and what i get is :
"ActiveRecord::RecordNotFound in UsersController#show"
"Couldn't find User with id=create"
And then code
# Use callbacks to share a common setup
def set_user
#user = User.find(params[:id])
end
# Permit only specific parameters
here's my User controller
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
def index
#users = User.all
end
def show
end
def create
#user = User.new(user_params)
respond_to do |user|
if #user.save(user_params)
user.html { redirect_to users_path, :notice => "User has been created!" }
else
user.html { redirect_to create_user_path(#user), :notice => "Sorry, couldn't create user. Try again!" }
end
end
end
def edit
end
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to users_path, :notice => "User has been updated!" }
else
format.html { redirect_to edit_user_path(#user), :notice => "Sorry, couldn't update user. Try again!" }
end
end
end
def destroy
#user.destroy
respond_to do |d|
d.html { redirect_to users_path, :notice => "User has been successfully destroyed :C !" }
end
end
private
# Use callbacks to share a common setup
def set_user
#user = User.find(params[:id])
end
# Permit only specific parameters
def user_params
params.require(:user).permit(:name, :email)
end
end
The thing is, the index page works perfectly fine, but if i try to go somewhere else, like /users/create i get that error.. I tried changing routes, rewriting the code, nothing helps.My routes are like this:
# Root '/'
root "users#index"
# Show Users
get "users/:id" => "users#show"
Can you guys help me ? I am literally stuck, as to how fix that problem :c
This should help you - you're missing resources :users, which creates a set of RESTful routes for your controller. This, combined with the other answers should help
You don't go to the create action via a URL. It's there to create a new user coming back from the new.html.erb file.
If you want to create a new user you could use /users/new and add a new method to your controller along the lines of:
def new
#user = User.new
end
You will also need to change your routes.rb file to add all the default actions like:
resources :users
I suggest you work through http://guides.rubyonrails.org/getting_started.html.
In your controller:
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
def index
#users = User.all
end
def show
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
redirect_to users_path, :notice => "User has been created!"
else
render :new
end
end
def edit
end
def update
if #user.update(user_params)
redirect_to users_path, :notice => "User has been updated!"
else
render :edit
end
end
def destroy
#user.destroy
redirect_to users_path, :notice => "User has been successfully destroyed :C !" }
end
private
def set_user
#user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:name, :email)
end
end
You are using all RESTful actions, so you can add to routes.rb:
resources :users
And remove this:
get "users/:id" => "users#show"
I've been putting the finishing touches on my app all day with the help of some useful answers here and would like to know how this feature can be executed. I have an idea set up in my post_controller file where I want to show the top 10 most recent posts created based on the date that they were created. I also plan on doing this for my comments as well laster on. I am showing all users post in the views/post/index.html.erb file. I wrote this line of code in the posts_controller: posts = Post.order('created_at DESC').limit(10). I've searched here thoroughly but don't understand how some other users got this to work, any insight? Thanks in advance.
posts_controller
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :vote]
before_action :require_user, only: [:new, :create, :edit, :update, :vote]
before_action :require_creator, only:[:edit, :update]
def index
posts = Post.order('created_at DESC').limit(10)
#posts = Post.all.page(params[:page]).per_page(10)
end
def show
#comment = Comment.new
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
#post.creator = current_user
if #post.save
flash[:notice] = "You created a post!"
redirect_to posts_path
else
render :new
end
end
def edit
end
def update
#post = Post.find(params[:id])
if #post.update(post_params)
flash[:notice] = "You updated the post!"
redirect_to post_path(#post)
else
render :edit
end
end
def vote
Vote.create(voteable: #post, creator: current_user, vote: params[:vote])
respond_to do |format|
format.js { render :vote } # Renders views/posts/vote.js.erb
end
end
private
def post_params
params.require(:post).permit(:url, :title, :description)
end
def set_post
#post = Post.find(params[:id])
end
def require_creator
access_denied if #post.creator != current_user
end
end
The posts variable you've declared in your index action will not be available in your view. What you need to do is update the line where you're retrieving the posts using instance variable as follows:
def index
#posts = Post.page(params[:page]).order('created_at DESC').per_page(10)
end
I am implementing blog app in ruby on rails where I want to restrict normal user( only admin can create) from creating new articles. For this purpose, I have put befor_filter in articles_controller.rb file which is following. I have hided create button from user in UI but still normal user can create new article by typing in address bar of browser.By using below code, normal user can not go on new article page but it gives me "undefined method `is_admin? when i type in address bar. For more info, I have implemented devise for user authentication.
class ArticlesController < ApplicationController
before_filter :is_user_admin, only: [:new, :create]
def is_user_admin
unless current_user.is_admin?
:root
return false
end
end
end
class ArticlesController < ApplicationController
before_filter :is_user_admin, only: [:new, :create]
def is_user_admin
unless current_user.is_admin?
:root
return false
end
end
def index
#articles = Article.all(:order => "created_at DESC")
end
def show
#article = Article.find(params[:id])
end
def new
#article = Article.new
end
def create
#article = Article.new(params[:article])
#article.user_id = current_user.id
#article.save
redirect_to article_path(#article)
end
def destroy
#article = Article.find(params[:id])
#article.destroy
redirect_to action: 'index'
end
def edit
#article = Article.find(params[:id])
end
def update
#article = Article.find(params[:id])
#article.update_attributes(params[:article])
flash.notice = "Article '#{#article.title}' Updated!"
redirect_to article_path(#article)
end
end
applicaiton_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
def after_sign_in_path_for(user)
if current_user.is_admin?
dashboard_index_path
else
:root
end
end
end
Basically, I want to restrict normal user (other than admin) to create , update or delete articles either from UI(this is done) or typing address in address bar.
I have no idea why i am getting this and what can i do to avoid this. Should i write above method in application_controller.rb file.
You propably want to redirect users to login so they can't access the action in your controller, if they're not admins. Hence, you could do something like this:
def is_user_admin
redirect_to(action: :index) unless current_user.try(:is_admin?)
end
Your current_user is nil apparently.
You should put before_filter :authenticate_user!, :except => [:show, :index] at the top of your controller in order to authenticate user.
Make sure that at least there is an user before checking for the permission. You can do that adding this code to every controller that requires an authentication:
before_filter :authenticate_user!
Doing this, you will always have a current user and hence will be able to check for its permission the way you pointed on your question.