I am literally pulling my hair out over here.
I am very new to Ruby on Rails. I did some tutorials and projects then decided to start off on my own on my own great project.
I got pretty far and am now adding Comments to my Tutorials...
(My "logic" got very confused. In my code, a comment is actually an answer to a "post." a reply is a "comment" to a tutorial.")
I used the Rails Console to create a reply. And that worked fine. So then I added the code "copy and pasted from an earlier project" using simple_form_for to create a comment on the tutorial page.
= simple_form_for(#reply, html: { class: 'form-horizontal' }) do |c|
= c.input :content, :label => false
= c.hidden_field :tutorial_id, :value => #tutorial.id
But when I reload my tutorial show page I get this error.
NoMethodError in Tutorials#show
Showing /home/gilbert/Rails_Projects/Seek-Rails-master/app/views/tutorials/show.html.haml where line #13 raised:
undefined method `replies_path' for #<#<Class:0x007fc519554cf0>:0x007fc5182f7b70>
Did you mean? replys_path
reply_path
I'm bad enough at what I'm doing that I don't know totally what all to describe...
I think part of the problem might be a large confusion between "reply and replys" vs "reply and replies"
maybe.
Here is my tutorial_controller.rb
class TutorialsController < ApplicationController
before_action :authenticate_user!, :except => [:index, :show]
def index
#all_tutorials = Tutorial.all
# #current_user_tuts = current_user.tutorials
# # #current_user_tuts = current_user.tutorials
end
def show
#tutorial = Tutorial.find(params[:id])
#replys = #tutorial.replys
#reply = Reply.new
end
def new
#tutorial = Tutorial.new
end
def edit
#tutorial = Tutorial.find(params[:id])
end
def create
#tutorial = Tutorial.new(create_params)
if #tutorial.save
redirect_to tutorial_path(#tutorial), notice: "Tutorial Created Succesfully."
else
redirect_to :back, flash: "Aw Snap! Error saving Tutorial. Try again Later."
end
end
def create_params
params.require(:tutorial).permit(:title, :body, :user_id)
end
def destroy
#tutorial = Tutorial.find(params[:id])
if #tutorial.delete
redirect_to "/posts/profile", notice: "Tutorial Deleted"
else
redirect_to "/posts/profile", notice: "Error deleting Tutorial, please try again."
end
end
def new_reply
#reply = Reply.new
end
end
And my replys_controller.rb
class ReplysController < ApplicationController
before_action :authenticate_user!, :except => [:index, :show]
def new
#reply = Reply.new
end
def create
#reply = Reply.new(create_params)
if #reply.save
redirect_to :back, notice: "Comment Created Succesfully."
else
redirect_to :back, flash: "Aw Snap! Error saving Comment. Try again Later."
end
end
def create_params
params.require(:reply).permit(:content, :tutorial_id, :user_id)
end
end
and Routes.rb
Rails.application.routes.draw do
devise_for :users
root to: "posts#index"
get "/posts/forum" => "posts#forum"
get "/posts/profile" => "posts#profile"
get "/posts/edit" => "posts#edit"
get "/posts/search" => "posts#search"
get "/tutorials/index" => "tutorials#index"
resources :posts
resources :comments
resources :tutorials
resources :replys
end
and reply.rb (model)
class Reply < ActiveRecord::Base
belongs_to :tutorial
end
and tutorial.rb (model)
class Tutorial < ActiveRecord::Base
belongs_to :user
has_many :replys
end
Sorry for the long post. I was hoping that it would suddenly come to me as I wrote it but it didn't.
I'd really appreciate the time spent on debugging this.
My code is also on github if you want to look at it or fork it or whatever...
https://github.com/GilGiy/Walk-Rails/tree/master/app
And if you have any tips about my code or something I'm doing completely wrong plz tell me...
Thanks a lot for you time....
Gil
EDIT:
Here's the output of "rake routes | grep replys"
replys GET /replys(.:format) replys#index
POST /replys(.:format) replys#create
new_reply GET /replys/new(.:format) replys#new
edit_reply GET /replys/:id/edit(.:format) replys#edit
reply GET /replys/:id(.:format) replys#show
PATCH /replys/:id(.:format) replys#update
PUT /replys/:id(.:format) replys#update
DELETE /replys/:id(.:format) replys#destroy
The problem is with you route resources :replys.
Your model name is Reply and its plural is replies so when you create a form with:
simple_form_for #reply
Rails will detect that #reply is a Reply object and try to create a path automatically by pluralizing the name i.e replies_path but you don't have that route, instead you have replys_path so its giving the error.
Though you can explicitly mention the url and change the path to correct one, I would highly suggest you to change the route to resources :replies to avoid this kind of problem in future.
Related
hoping someone can help. I've been searching through other "param is missing" questions, but can't seem to figure out what's wrong.
In my routes file I have this nested resource "actions"
resources :jobs do
resources :actions
end
The associated models. Ignore "action_reference". That's something else.
class Job < ActiveRecord::Base
has_many :actions
end
class Action < ActiveRecord::Base
belongs_to :job
belongs_to :action_reference
end
And I'm trying to create a new action by making a POST request using button_to
Here's the ActionsController
class ActionsController < ApplicationController
before_action :set_job
before_action :set_action, only: [:show, :edit, :update]
# GET /jobs/:job_id/actions/:id
def show
end
# GET /jobs/:job_id/actions/new
def new
#action = Action.new
end
# GET /jobs/:job_id/actions/:id/edit
def edit
end
# POST /jobs/:job_id/actions/
def create
#action = #job.actions.create(action_params)
if #action.save
flash[:success] = "Next step successfully added."
redirect_to jobs_path
else
flash[:danger] = #action.errors.full_messages.join(", ")
redirect_to new_job_action_path
end
end
# PATCH to /jobs/:job_id/actions/:id
def update
if #action.update(action_params)
flash[:success] = "Next step successfully updated."
redirect_to jobs_path
else
flash[:danger] = #action.errors.full_messages.join(", ")
redirect_to edit_job_action_path
end
end
private
def set_job
#job = Job.find(params[:job_id])
end
def set_action
#action = Action.find(params[:id])
end
def action_params
params.require(:action).permit(:action_reference_id, :job_id, :completed_at, :next_action_date)
end
end
And here's my button_to
<%= button_to answer[:text], post_action_jobs_path(#job), method: "post", params: { action: { action_reference_id: answer[:action_reference_id], job_id: #job_id , completed_at: answer[:action_completed_at], next_action_date: answer[:next_action_date] } }, type: "button", class: "btn btn btn-info btn-block" %>
I know the problem has something to do with the arguments I'm passing to the post_action_jobs_path in the view or the ones I'm passing to action_params in the controller, but I can't figure it out.
When I run this I get the error:
undefined method `permit' for "create":String Did you mean? print
I saw some thread a little while ago saying something about "action" being a reserved word in Rails, so you have to use something else, but if that's true I'm not sure how to go about that.
Any help would be greatly appreciated :)
Yes unfortunately this is due to "action" being an existing method inside rails controllers. It is used to get the name of the action that has been called. In this case "action" will equal the string "create".
One thing you could do would be to rename you Action model to JobAction and use params.require(:job_action)
Sadly I couldn't seem to find away around this, so I renamed my "actions" table and replaced every reference to "action" with a different word "step". Now it works!
I have looked at many similar posts, but can't seem to get rid of this record not found error I get when trying to use my destroy method. The two models in question are workouts.rb and exercises.rb. A workout has_many exercises.
The error I'm getting is Couldn't find Workout without an ID on the third line of the below code from my exercises_controller:
def destroy
#workout = Workout.friendly.find(params[:workout_id])
exercise = #workout.exercises.find(params[:id])
My exercise.rb model is:
class Exercise < ActiveRecord::Base
belongs_to :workout
belongs_to :user
has_many :reports
validates :user, presence: true
end
My workout.rb model is:
class Workout < ActiveRecord::Base
extend FriendlyId
friendly_id :name, use: :slugged
belongs_to :user
has_many :exercises
has_many :reports
validates :user, presence: true
end
And my full exercises_controller is:
class ExercisesController < ApplicationController
before_action :authenticate_user!
def index
#exercises = Exercise.all
end
def new
#exercise = Exercise.new
end
def create
#workout = Workout.friendly.find(params[:workout_id])
exercise = #workout.exercises.new(exercise_params)
exercise.user = current_user
if exercise.save
flash[:notice] = "Results saved successfully."
redirect_to [#workout]
else
flash[:alert] = "Results failed to save."
redirect_to [#workout]
end
end
def destroy
#workout = Workout.friendly.find(params[:workout_id])
exercise = #workout.exercises.find(params[:id])
if exercise.destroy
flash[:notice] = "Exercise was deleted successfully."
redirect_to [#workout]
else
flash[:alert] = "Exercise couldn't be deleted. Try again."
redirect_to [#workout]
end
end
private
def exercise_params
params.require(:exercise).permit(:name, :needs_seconds, :needs_weight, :needs_reps)
end
def authorize_user
exercise = Exercise.find(params[:id])
unless current_user == current_user.admin?
flash[:alert] = "You do not have permission to create or delete an exercise."
redirect_to [exercise.workout]
end
end
end
My routes are simple:
resources :workouts
resources :exercises
EDIT:
The code calling the deletion is:
<%= link_to "Delete #{exercise.name}", exercise_path, method: :delete, data: { confirm: 'Are you sure?' } %>
Any ideas where this error is coming from?
We can't do much for you without the code. However, a common mistake would be to forget the :id on the route.
Is see that you auto-generate them with Rails, so it's easy to forget that a destroy action for your exercice resource would be a DELETE action on /exercises/:id
Mind the id in the route !
Moreover, reading you controller, it looks like you expect a workout_id, then the correct routing for that would be :
resources :workouts do
resources :exercices
end
Which is gonna enable to have these routes :
GET /workouts/:workout_id/exercices(.:format) exercices#index
POST /workouts/:workout_id/exercices(.:format) exercices#create
GET /workouts/:workout_id/exercices/new(.:format) exercices#new
GET /workouts/:workout_id/exercices/:id/edit(.:format) exercices#edit
GET /workouts/:workout_id/exercices/:id(.:format) exercices#show
PATCH /workouts/:workout_id/exercices/:id(.:format) exercices#update
PUT /workouts/:workout_id/exercices/:id(.:format) exercices#update
DELETE /workouts/:workout_id/exercices/:id(.:format) exercices#destroy
GET /workouts(.:format) workouts#index
POST /workouts(.:format) workouts#create
GET /workouts/new(.:format) workouts#new
GET /workouts/:id/edit(.:format) workouts#edit
GET /workouts/:id(.:format) workouts#show
PATCH /workouts/:id(.:format) workouts#update
PUT /workouts/:id(.:format) workouts#update
DELETE /workouts/:id(.:format) workouts#destroy
Mind the workout_id in the nested routes.
So if you have the workout with id = 3, for exercice with id = 23, you'll be able to send a DELETE on /workouts/3/exercices/23 and in your ExercicesController, you will have access to these two values :
params[:id] = 23
params[:workout_id] = 3
Like you expect, I think.
I went overboard, hope it was useful. I tried to enrich my answer based on your code.
UPDATE: I have solved the NilClass issue! Thanks!
Now I am having a problem with:
unknown attribute 'sessionId' for Room.
SOLVEDI am currently having some issues where my code is telling me I have an error of "undefined method `create_session' for nil:NilClass" on line 9. I will provide the files.
This is the specific line:
#new_room = Room.new(strong_param)
rooms_controller.rb
class RoomsController < ApplicationController
require "opentok"
before_filter :config_opentok,:except => [:index]
def index
#rooms = Room.where(:public => true).order("created_at DESC")
#new_room = Room.new
end
def create
session = #opentok.create_session :media_mode => :routed
params[:room][:sessionId] = session.session_id
#new_room = Room.new(strong_param)
respond_to do |format|
if #new_room.save
format.html { redirect_to(“/party/”+#new_room.id.to_s) }
else
format.html { render :controller => ‘rooms’, :action => “index” }
end
end
end
def party
#room = Room.find(params[:id])
#tok_token = #opentok.generate_token #room.sessionId
end
private
def config_opentok
if #opentok.nil?
#opentok = OpenTok::OpenTok.new ########, "#########################################"
end
end
def strong_param
params.require(:room).permit(:name,:sessionId)
end
end
rooms.rb (Models)
class Room < ActiveRecord::Base
end
I've tried several different modifications to these files to make my program work. I can get the listing page to work but once I try and actually create a new room, I receive this error message.
Look forward to any advice you can provide.
You are missing the before_filter :config_opentok,:except => [:index] line from the blog post in your previous post (https://railsfornovice.wordpress.com/2013/01/01/video-chatting-in-ruby-on-rails/)
In my Rails app I have invoices which in turn can have many projects.
model:
class Invoice < ActiveRecord::Base
attr_accessible :project_id
end
controller:
class InvoicesController < ApplicationController
before_filter :authorized_user, :only => [ :show, :edit, :destroy ]
before_filter :authorized_project, :only => [ :create, :update ]
def create # safe
#invoice = #project.invoices.build(params[:invoice])
if #invoice.save
flash[:success] = "Invoice saved."
redirect_to edit_invoice_path(#invoice)
else
render :new
end
end
def update # not safe yet
if #invoice.update_attributes(params[:invoice])
flash[:success] = "Invoice updated."
redirect_to edit_invoice_path(#invoice)
else
render :edit
end
end
private
def authorized_user
#invoice = Invoice.find(params[:id])
redirect_to root_path unless current_user?(#invoice.user)
end
def authorized_project
#project = Project.find(params[:invoice][:project_id])
redirect_to root_path unless current_user?(#project.user)
end
end
My biggest concern is that a malicious user might, one day, create an invoice that belongs to the project of another user.
Now thanks to the help of some people on this board I managed to come up with a before_filter that makes sure that this won't happen when a project is created.
The problem is I don't understand how to apply this filter to the update action as well.
Since the update action does not make use of Rails' build function, I simply don't know how to get my #project in there.
Can anybody help?
In your case I would start from current_user, not #project (provided User has_many :invoices):
current_user.invoices.build(params[:invoice])
Also instead of explicitly check current_user?(#invoice.user) you can do:
def find_invoice
#invoice = current_user.invoices.find(params[:id])
end
def find_project
#project = current_user.projects.find(params[:invoice][:project_id])
end
Wrong invoice or project will throw 500 which you may or may not want to handle.
If User has_many :invoices, :through => :projects and Project hence has_many :invoices then:
def find_invoice
#invoice = #project.invoices.find(params[:id])
end
The #project.invoices.build method creates a new Invoice that is automatically associated with that particular #project. You don't have to do any work, and there's no risk of it being linked to the wrong project.
You'll want to be sure that project_id is not an accessible attribute, though.
Building a forum in ruby for fun and to learn the language. To start this off, i understand basic constructs, but I am very new to server-side languages and am primarily a front-end developer. I am trying to extend my skills.
I don't necessarily want you to code for me (although code examples would be appreciated), but I would like you to explain to me why my code is terrible, which I'm sure it is and tell me how to fix it. Just need some help understand how to relate two models togethers and how to set up that relation in the controllers.
Thanks!
Here are my two models:
Post model:
class Post < ActiveRecord::Base
belongs_to :topic
end
Topic model:
class Topic < ActiveRecord::Base
belongs_to :user
has_many :posts
end
Now here come the controllers. These are where I am really lost. I got the topic creation working, and I tried to just copy what I did in the topic controller. I pretty much knew it wasn't going to work, but I am sorta lost. Here it is...
Topic Controller
class TopicsController < ApplicationController
def index
#topics = Topic.order("sticky desc")
end
def show
#topic = Topic.find(params[:id])
end
def new
#topic = Topic.new
end
def create
#topic = Topic.new(topic_params)
#topic.user = current_user
if #topic.save
redirect_to #topic, notice: "Created topic."
else
render :new
end
end
def edit
#topic = Topic.find(params[:id])
end
def update
#topic = Topic.find(params[:id])
if #topic.update_attributes(topic_params)
redirect_to topics_url, notice: "Updated topic."
else
render :edit
end
end
def destroy
#topic = Topic.find(params[:id])
#topic.destroy
redirect_to topics_url, notice: "Destroyed topic."
end
private
def topic_params
params.require(:topic).permit(:name, :post_content, :sticky)
end
end
Posts Controller
class PostsController < ApplicationController
def index
#posts = Post.order("sticky desc")
end
def show
#post = Post.find(params[:id])
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
#post.user = current_user
if #post.save
redirect_to topics_url, notice: "Post created."
else
render :new
end
end
def edit
#post = Post.find(params[:id])
end
def update
if #post = Post.find(params[:id])
redirect_to topics_url, notice: "Updated post."
else
render :edit
end
end
def destroy
#post = Post.find(params[:id])
#post.destroy
redirect_to topics_url, notics: "Post removed."
end
private
def post_params
params.require(:posts).permit(:content, :created_at, :updated_at)
end
end
I don't believe the views are an issue, and I will post a new question if there is once I get the controller logic figured out.
Again, any help would be appreciated. Please just no comments like, "you should really start back at the beginning", or "you aren't experienced enough, learn this first", because I know I am not experienced, hence why I am here asking you all.
You can show how you would code it, or just explain the logic that needs implemented to me, either is appreciated!
Thanks a ton everyone!
EDIT
I am getting a routing error actually. So obviously the routing is wrong, wasn't sure if it had something to do with the controller code tho: Here is the specific error. (this occurs when I try to click into a topic (I can edit and destroy topics, just not click into them)
Routing Error
No route matches {:action=>"new", :controller=>"posts"}
Try running rake routes for more information on available routes.
Here is my routes files so far:
Forum::Application.routes.draw do
get 'signup', to: 'users#new', as: 'signup'
get 'login', to: 'sessions#new', as: 'login'
get 'logout', to: 'sessions#destroy', as: 'logout'
resources :sessions
resources :topics do
resources :posts
end
resources :users
root to: 'topics#index'
end
Serve is a little Rack-based web server that makes it simple to serve ERB or HAML from any index. Serve is an optimal apparatus for building HTML models of Rails applications. Serve can likewise deal with SASS, Textile, and Markdown in the event that the suitable diamonds are introduced.
enter image description here