Rails link_to static pages issue - ruby-on-rails

I don't know an awful lot about Rails and I've inherited this project. For the past few days I've been trying to get my head around, 'link_to', and 'routes.rb'. This stuff is driving me mad - I've spent the whole day looking at it, pasting bits of code into bare projects, where it works..but I just don't understand the error I'm getting here, or how to go about solving it, so if you have any ideas....
In my page _signed_in_header.html.erb I have:
FAQ
In my routes.rb I have:
get "staticpages/faq"
I know this is set up correct, because when I start a sample project from scratch, it works.
But in this particular project I've inherited I get the error:
NoMethodError in Staticpages#faq
Showing /home/christophecompaq/Populisto/app/views/layouts/_signed_in_header.html.erb where line #48 raised:
undefined method `model_name' for NilClass:Class
Extracted source (around line #48):
45:
46: <div class='search-box'>
47: <%= simple_form_for #review, :url => search_index_path, :method => :post, :html => { :class => 'form-horizontal'} do |f| %>
48:
49: <%= f.input :search_ids, :collection => #data, :as => :grouped_chosen,
50: :group_method => :last, :prompt => false,
51: :input_html => { :class => 'span5', :multiple => true },
Trace of template inclusion: app/views/layouts/_header.html.erb, app/views/layouts/application.html.erb
Rails.root: /home/christophecompaq/Populisto
Application Trace | Framework Trace | Full Trace
app/views/layouts/_signed_in_header.html.erb:48:in `_app_views_layouts__signed_in_header_html_erb___586079249_69970641688720'
app/views/layouts/_header.html.erb:1:in `_app_views_layouts__header_html_erb__1905506502_69970640142220'
app/views/layouts/application.html.erb:21:in `_app_views_layouts_application_html_erb___1868096314_69970642536740'
Edit: I was asked to show my review controller code, so here it goes:
class ReviewsController < FrontEndController
respond_to :html, :json
before_filter :with_google_maps_api
def index
#review = Review.new
end
def create
#review = Review.create((params[:review] || {}).merge(:user_id => current_user.id))
if #review.save
redirect_to landing_page, :notice => I18n.t('write_review.review_successfully_created')
else
render :action => :index
end
end
def show
#review = Review.find(params[:id])
end
def edit
#review = Review.find(params[:id])
end
def update
#review = Review.find(params[:id])
if #review.update_attributes(params[:review])
else
render :edit
end
end
def destroy
#review = Review.find(params[:id])
#review.destroy
end
def repost
#review = Review.find(params[:id])
#review.repost(current_user)
end
def reject
#review = Review.find(params[:id])
current_user.reject #review
end
end
Anyway, if you have any ideas what could be wrong, I'd be delighted to know....Thanks.
Christophe.

in your route file, use this code
get "staticpages/faq", :as => 'faq_page'
The 'as' will generate 2 helper functions: faq_page_url and faq_page_path that you can use in your code

i hope this will help, i think we have the same issue but i've managed to fix this using this:
in my routes.rb
match 'pages/:action', :controller => "pages"
and in my view:
= link_to "About", {:controller => 'pages', :action => 'about'}

The error is happening during rendering of the layout template, not the controller view.
If you're testing the faq page you'll be hitting the StaticpagesController, not the ReviewController you pasted right? And presumably StaticpagesController does not set #review... hence your exception.
So either try wrapping the search box code in a conditional like:
<% if #review %>
... put your review search form here ...
<% end %>
or if the search is supposed to present on all pages, ensure it's populated on all pages. Maybe add a before_filter on your base controller class with something like
class ApplicationController < ....
before filter :ensure_review_set
private
def ensure_review_set
#review ||= Review.new
end
end
The search form is also referencing #data if the search_ids field. That will also need to be initialised by any controllers using this layout.
More generally, if your version of rails supports it, I'd very very highly recommend the better_errors gem for quickly debugging errors such as this.

Related

ROR5: 'param is missing or the value is empty' error with adding Bookmarks

I have an app where users can ask questions and bookmark certain questions. I'm done with the users, questions, and answers, so I've added a BookmarkController & Bookmarks model. At first, I considered using associations, but my app has a few associations already so I'm (or I've attempted at) using query parameters such as user_id and question_id to fetch bookmarks.
The structure is a bit like StackOverflow. A user navigates to a single question view and bookmarks it on that page. This creates a new bookmark model containing the user_id of current_user and the question_id. The user can go to his profile to view all the questions he bookmarked, fetched using his user_id. (Answers cannot be bookmarked. Only questions.)
I've been getting a 'param is missing or the value is empty: bookmark' error, although I have followed similar steps I did for my QuestionsController. It would be great if someone could help me out in identifying what's wrong/bad about my code!
rake routes (first part omitted)
bookmark_question PUT /questions/:id/bookmark(.:format) questions#bookmark
questions GET /questions(.:format) questions#index
POST /questions(.:format) questions#create
new_question GET /questions/new(.:format) questions#new
edit_question GET /questions/:id/edit(.:format) questions#edit
question GET /questions/:id(.:format) questions#show
PATCH /questions/:id(.:format) questions#update
PUT /questions/:id(.:format) questions#update
DELETE /questions/:id(.:format) questions#destroy
route.rb (excerpt)
# Questions
get '/questions/:id' => 'bookmarks#create'
show.html.erb (questions#show)
<% if current_user %>
<%= link_to "Bookmark", :controller => 'bookmarks', :action => 'create' %>
<% end %>
BookmarksController
class BookmarksController < ApplicationController
def new
#bookmark = Bookmark.new
end
def create
#question = Question.find(params[:id]) # when I delete this line, I get a new error - "undefined local variable 'params'"
#bookmark = Bookmark.new(bookmark_params)
#bookmark.user_id = current_user.id
#bookmark.question_id = #question.id
#bookmark.save
redirect_to #question
end
def destroy
end
private
def bookmark_params
params.require(:bookmark).permit(:user_id, :question_id)
end
end
Bookmark model
class Bookmark < ApplicationRecord
validates :user_id, presence: true
validates :question_id, presence: true
end
QuestionsController
(at the moment, contains no reference to Bookmarks. I thought so because I did the routing, but this might be where I'm going wrong)
class QuestionsController < ApplicationController
def index
#questions = Question.all
end
def show
#question = Question.find(params[:id])
#answers = Answer.all
# Delete only appears when no answers
#deletable = (current_user== User.find(#question.user_id)) && (#question.answers.all.size==0)
end
def new
#question = Question.new
end
def create
if logged_in?
#question = Question.new(question_params)
#question.user_id = current_user.id
#question.save
redirect_to #question
else
redirect_to login_path
end
end
def destroy
#question = Question.find(params[:id])
#question.destroy
redirect_to root_path
end
private
def question_params
params.require(:question).permit(:picture_url, :country, :educational_level, :topic)
end
end
profile index.html.erb (just for ref)
<% if (#bookmarks.count == 0) %>
///
<% else %>
<%= #bookmarks.each do |bookmark| %>
<!-- Show bookmark content here like Question.find(bookmark.question_id) etc -->
<% end %>
<% end %>
I have looked a the previous qns that have the same error as me. But they were all using associations. I hope to not use associations as the bookmark model only needs to keep a record of the user id and qn id.
UPDATE
So, referring to the answers given, I updated my erb to:
<% if logged_in? %>
<%= link_to "Bookmark", :controller => 'bookmarks', :action => 'create', bookmark: {user_id: current_user.id, question_id: #question.id} %>
<% end %>
hence specifying the controller and action (and the params) that need to be directed. But rails sends an error:
No route matches {:action=>"create", :bookmark=>{:user_id=>2, :question_id=>4}, :controller=>"bookmarks", :id=>"4"}
So I assume it was a routing problem. As Pavan suggested, I did consider nesting my resources, but the nesting is already one level deep, as such:
resources :questions do
resources :answers
end
And I reckon doing something like:
resources :questions do
resources :bookmarks # or resources :bookmarks, only: create
resources :answers
end
won't work. (And it didn't :( )
I'm not so sure how to get this routing problem fixed (tried Googling). Thanks.
param is missing or the value is empty: bookmark
The reason for the error is bookmark_params expects a :bookmark key to be present in the params hash, which in your case is missing since you are not passing any.
Change link_to like below:
<% if current_user %>
<%= link_to "Bookmark", :controller => 'bookmarks', :action => 'create', bookmark: {user_id: current_user.id, question_id: #question.id} %>
<% end %>
Also, the route get '/questions/:id' => 'bookmarks#create' isn't right and would conflict with this route question GET /questions/:id(.:format) questions#show. I would instead recommend building nested routes
resources :users do
resources :questions do
resources :bookmarks, only: [:create]
end
end
Update:
Along with the above, you should change #question = Question.find(params[:id]) to #question = Question.find(params[:bookmark][:question_id])
'param is missing or the value is empty: bookmark, this error means that, there is no bookmark key present in your params object, but you defined your bookmark_params to have one:
def bookmark_params
params.require(:bookmark).permit(:user_id, :question_id)
end
That's why it's throwing the above error message.
You should make sure you send the user_id and question_id key/value pairs under the bookmark key. Something like this:
bookmark: { user_id: 1, question_id: 2}.
So, your code should look something like this (adding the bookmark to params):
<%= link_to "Bookmark", :controller => 'bookmarks', :action => 'create', bookmark: {user_id: current_user.id, question_id: #question.id} %>

ruby on rails recieving error: First argument in form cannot contain nil or be empty

We have an error in our erb files and the screen shot is here
We have everything in games.html.erb as below
<h1>Games#game</h1>
<%= form_for(#game) do |f| %>
<div class="game-field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="actions">
<%= submit_tag "Game Created", :class=> "btn" %>
</div>
<% end %>
and here is the controller
class GamesController < ApplicationController
before_filter :store_location, :only => [:index, :show]
before_filter :require_user, :only => :show
before_filter :assign_game, :only => [:show, :destroy]
def index
#game = Game.new
end
def new
#game = Game.new
end
#game.add_player_from_user(current_user)
respond_to do |format|
format.html
format.json do render :json => {
:shouldStartNewRound => #game.is_ready_for_new_round?,
:shouldPassCards => #game.is_ready_to_pass?,
:isStartingFirstRound => #game.rounds.empty?,
:shouldReloadWaitAutoPlay => #game.should_reload?(current_player),
:shouldReloadAndJustWait => #game.should_reload_and_wait?(current_player)
}
end
end
end
def create
#game = Game.new(params[:game])
api_key = ""
api_secret = ""
#openTok = OpenTok::OpenTokSDK.new api_key, api_secret
session = #openTok.create_session request.remote_addr
#game.update_attributes(:session_id => session.session_id)
name = game[:name] # input from html
#game[:name] = name # setting input into db object (model)
if #game.save
redirect_to #game, alert: "game created"
else
render action: 'new'
end
end
def destory
#game.destory
redirect_to games_url
end
def reload
reload_partial
end
end
We are trying to create a deuces card game and we have bee stuck on that single problem. I have also looked for other similar problem that people have asked and we were not able to find the issue, it says that we have to put .new function to initialize the data. But the error is still showing up. Please help us!
You don't have a #game method in your GameController class.
Rename your #index action into #game or your View file.
I don't know how your routes file looks like but I suppose that the index action is the action that you call if somebody calls the root route, so http://localhost:3000/. If that's right then you have to rename game.html.erb into index.html.erb.
It looks like you are calling the action #game on controller Games. There is no #game method defined on the controller, so the instance variable #game never gets defined like it does in #index or #new. You can create a #game method in the controller and define #game in that method as needed.
Also, you have some code in the controller that needs to be inside of a method, starting at #game.add_player_from_user(current_user). Right now it's just executing at load time and probably not doing anything that makes any sense.
Finally, I noticed that you misspelled 'destroy' in a couple of places - search for 'destory' and replace with 'destroy' to avoid problems later.

passing variables in redirect_to

In my Rails application, in routes.rb I have
match "show_fail" => "Posts#show_fail"
In posts_controller.rb:
def create
...
return redirect_to show_fail_path, :title => #post.title
end
def show_fail
end
In show_fail.html.erb:
Unsuccessful posting of post title <%= title %>
But I got an error undefined local variable or method 'title'. Why does it not know about the title variable, and how can I fix it?
redirect_to show_fail_path(:title => #post.title)
and take it from params[:title]

Routes generated paths have stopped working

I'm creating a blog using Rails 3.2.5 and have been using link_to's to each action using the resource paths generated by Routes (i.e. for my code_entries: code_entries_path, new_code_entry_path, etc.) throughout the site. All of a sudden whenever I try to access a page I get this error:
undefined local variable or method `controller' for #<CodeEntriesController:0x007f887f8b3300>
This error is from my index action on my code_entries_controller.rb, but no matter which action I try to go to in any controller I get this error on every link_to with a Routes resource path. It was working fine before and I'm not sure what would have caused this.
Since this question is in the context of my code_entries, here is the code for code_entries_controller.rb, /code_entries/index.html.haml, routes.rb and the error I've been getting but in the context of the action code_entries#index:
code_entries_controller.rb
class CodeEntriesController < ApplicationController
before_filter :authenticate_action
def index
#entries = CodeEntry.order("created_at desc")
end
def new
#entry = CodeEntry.new
end
def show
#entry = CodeEntry.find_by_id(params[:id])
end
def create
#entry = CodeEntry.new(params[:code_entry])
if #entry.save
redirect_to code_entry_path(#entry), :notice => "#{#entry.title} has been created"
else
puts #entry.errors.messages.inspect
render "new"
end
end
def edit
#entry = CodeEntry.find_by_id(params[:id])
end
def update
#entry = CodeEntry.find_by_id(params[:id])
if #entry.update_attributes(params[:code_entry])
redirect_to code_entry_path(#entry), :notice => "#{#entry.title} has been updated"
else
puts #entry.errors.messages.inspect
render "edit"
end
end
def destroy
#entry = CodeEntry.find_by_id(params[:id])
#entry.destroy
redirect_to code_entries_path, :notice => "#{#entry.title} has been deleted"
end
end
/code_entries/index.html.haml
%h1 Hello!
%br
- #entries.each do |e|
%h2= link_to e.title, code_entry_path(e)
%h3= e.updated_at
= raw excerpt(e, 200)
%br
- if current_user
= link_to "Edit", edit_code_entry_path(e)
= button_to "Delete", code_entry_path(e), :confirm => "Really really?", :method => :delete
%hr
routes.rb
Blog::Application.routes.draw do
resources :users
resources :code_entries
resources :food_entries
resources :inclusive_entries
resources :sessions
root :to => "home#index"
get "login" => "sessions#new", :as => "login"
get "logout" => "sessions#destroy", :as => "logout"
get "users/new"
end
NameError in Code_entries#index
Showing /Users/kyle/Projects/blog/app/views/code_entries/index.html.haml where line #4 raised:
undefined local variable or method `controller' for #<CodeEntriesController:0x007f887f813418>
Extracted source (around line #4):
1: %h1 Hello!
2: %br
3: - #entries.each do |e|
4: %h2= link_to e.title, code_entry_path(e)
5: %h3= e.updated_at
6: = raw excerpt(e, 200)
7: %br
Rails.root: /Users/kyle/Projects/blog
Application Trace | Framework Trace | Full Trace
app/views/code_entries/index.html.haml:4:in `block in _app_views_code_entries_index_html_haml___3334012984247114074_70112115764360'
app/views/code_entries/index.html.haml:3:in `_app_views_code_entries_index_html_haml___3334012984247114074_70112115764360'
Request
Parameters:
None
Show session dump
Show env dump
Response
Headers:
None
I had made a method inside of application_controller.rb and used it as an argument with helper_method. Since it was inside of application_controller.rb and not application_helper.rb I had used the tag include ActionView::Helpers::UrlHelper so I could use a link_to inside the helper method. Somehow that include statement was making it blow up, but once I removed the include statement and moved the helper method into application_helper.rb everything turned out fine!

Is there a clean approach to implement acts_as_commentable in a Rails application?

The README does not show how to handle the controller and view aspects of setting up this plugin. I have been searching for a couple hours and can't find anything that shows how to use this plugin.
After even more searching, I gave up on finding a tutorial and came up with this. If anyone can point out a better / cleaner way to do this, please let me know. Otherwise, here is what I am using now in case this will benefit anyone else.
First, install the plugin with script/plugin install http://github.com/jackdempsey/acts_as_commentable.git -r 2.x
Then, generate the comment model and migration with script/generate comment and migrate the database with rake db:migrate
The tricky bit is nesting comments under other resources in a polymorphic way. Here is what I did:
# In config/routes.rb
map.resources :comments, :path_prefix => '/:commentable_type/:commentable_id'
# In app/controllers/comments_controller.rb
before_filter :load_commentable
def create
#comment = #commentable.comments.build(params[:comment])
#comment.user = current_user
respond_to do |format|
if #comment.save
format.html { redirect_to #commentable }
else
format.html { render :action => 'new' }
end
end
end
protected
def load_commentable
#commentable = params[:commentable_type].camelize.constantize.find(params[:commentable_id])
end
# In app/views/comments/_form.html.erb
<%= form_for(:comment, :url => comments_path(commentable.class.to_s.underscore, commentable.id)) do |f| %>
# In app/views/model_that_allows_comments/show.html.erb
<%= render :partial => 'comments/form', :locals => {:commentable => #model_that_allows_comments} %>
I think that shows the relevant parts clearly enough to understand what is happening. It makes it possible to add acts_as_commentable to any model. You just have to pass in the commentable object in the locals hash when rendering the comments form and the same comments controller / view code should work.
acts_as_commentable merely exposes you a Comment model and takes care of the plumbing between that model and your commentable models. It doesn't give you any controllers or views. You are responsible for deciding how you want to implement this part of your application.
It is pretty straightforward, though. For example...
# in routes.rb
map.resources :posts, :has_many => :comments
# in your comments controller...
class CommentsController < ApplicationController
before_filter :get_post
def get_post
#post = Post.find(params[:post_id])
end
def index
#comments = #post.comments.all # or sorted by date, or paginated, etc.
end
end
# In your haml view...
%h1== Comments for #{#post.title}:
%ul
- comments.each do |comment|
%h3= comment.title
%p= comment.comment
You'll see the comments for a particular post when you go to /posts/1/comments now.
I think the best way to add comments to any model is creating a method called comment in your ApplicationController.rb file like this.
def comment
# Extracts the name of the class
klass = self.class.to_s[/\A(\w+)sController\Z/,1]
# Evaluates the class and gets the current object of that class
#comentable_class = eval "#{klass}.find(params[:id])"
# Creates a comment using the data of the form
comment = Comment.new(params[:comment])
# Adds the comment to that instance of the class
#comentable_class.add_comment(comment)
flash[:notice] = "Your comment has been added!"
redirect_to :action => "show", :id => params[:id]
end
and then just create some partial _comment.rb to use it in any model you want
<%= form_tag :action => "comment", :id => Your_model_goes_here %>
<p><label for="comment_title">Title</label><br/>
<%= text_field 'comment', 'title' %></p>
<%= text_area "comment", "comment", :rows => 5, :cols => 50 %> <br />
<%= submit_tag "Comment!.." %>
</form>
I hope it's useful for someone...

Resources