I am rendering a variable from the controller action . The code is :
def show1
if request.post?
#bookmark = Bookmark.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #bookmark }
end
end
end
This is the action 'show'. The 'show' view is as follows:
<% #array_bookmark = #bookmark.class == Array ? #bookmark : [#bookmark] %>
<% #array_bookmark.each do |book| %>
<li><%= book.url%>
<b>Title:</b>
<li><%= book.title%>
<% end %>
This should print the records in bookmarks table with attributes url and title. But it gives an error:
NoMethodError in Bookmark#show
Showing C:/Sites/newapp/app/views/bookmark/show.html.erb where line #10 raised:
undefined method `url' for nil:NilClass
Extracted source (around line #10):
7: <b>Url:</b>
8: <% #array_bookmark = #bookmark.class == Array ? #bookmark : [#bookmark] %>
9: <% #array_bookmark.each do |book| %>
10: <li><%= book.url%></li>
11: <b>Title:</b>
12: <li><%= book.title%></li>
13: <li><%= book.tags%></li>
This is the error i get . Can i anyone gimme a proper solution so that i can print the table records in the view properly?
The problem is that you should have used my answer to your earlier question:
<% Array(#bookmark).each do |book| %>
The code you have checks whether #bookmark is an instance of the class Array; if it is nil, this will return false and #array_bookmark will be assigned [nil]. Then when you iterate over it in your each loop you'll get a nil value for book. By using Array() you avoid this problem: Array(nil) evaluates to an empty array, so the loop never executes and you don't get an error.
Related
I'm using form_for to create a chatroom and when I view the page I get the following error:
NoMethodError in Chatrooms#new
undefined method `chatrooms_path' for #<#<Class:0xa862b94>:0xa5307f0>
Here's the code for the view, located in app/views/chatrooms/new.html.erb:
<div class="center">
<%= form_for(#chatroom) do |f| %>
<%=f.text_field :topic%>
<br>
<%=f.submit "Start a discussion", class: "btn btn-large btn-primary"%>
<% end %>
</div>
Here's the relevant controller:
class ChatroomsController < ApplicationController
def new
#chatroom = Chatroom.new
end
def show
#chatroom = Chatroom.find(params[:id])
end
end
If I change the line
<%= form_for(#chatroom) do |f| %>
to
<%= form_for(:chatroom) do |f| %>
it works fine.
I've searched around for similar questions but none of the solutions have worked for me. Help?
It is because you didn't create route/action for ChatroomsController. When you render new form it is pointing to create action by default, if you want to change handler action, use
form_for #chatroom, :url => some_other_path
Using the google maps API and rails 3.2.1 I have page allowing to move the business marker on a map to correct it's position. The business model has latitude and longitude (amongst others). The relevant part is:
<%= form_for :business, :url => { :action => "updatemap" }, :id => 'updatebutton' do |f| %>
<%= f.hidden_field :latitude %>
<%= f.hidden_field :longitude %>
<br />
<%= f.submit "Save" %>
<% end %>
The method updatemap is:
def updatemap
#business = Business.find(params[:id])
#business.latitude = params([:business][:latitude])
#business.longitude = params([:business][:longitude])
if #business.save!
redirect_to business_path(#business), :flash => { :success => "The business was updated!" }
else
render 'changemap', :flash => { :error => "An error occured." }
end
end
Running the debugger, params([:business][:latitude]) and params([:business][:longitude]) give the correct value of the new map coordinates (e.g. "45.273739" for latitude). But there is an error:
TypeError in BusinessesController#updatemap
can't convert Symbol into Integer
(the line of the error is the #business.latitude = params([:business][:latitude]) line)
I also tried with
...
if #business.update_attributes(params[:business])
...
but the error is the same. What causes the error and how can I correct it?
You are writing params([:business][:latitude]) rather than params[:business][:latitude]. That means that [:business] is actually a method call on self, rather than params. Presumably the class which this code is part of has a [] method, but it expects an integer rather than :business.
I really can't figure out why I can't access the user_id field for the class Post. I have it as a field in my database (I can see it, and it isn't blank. Yet for some reason, I'm getting this error:
undefined method `user_id' for #<Class:0x103497448>
Extracted source (around line #10):
7: <h2>Topics</h2>
8: <% #board.topics.each do |topic| %>
9: <% #post = topic.posts(1) %>
10: <b><%= User.find(#post.user_id).username %> says <%= link_to topic.subject, [#board, topic] %></b><br />
11: <% end %>
12: <% end %>
13:
topic.posts(1) will return an array. Hence #<Class:0x103497448>
The right way to get the first post for a topic would be
9: <% #post = topic.posts.first %>
10: <b><%= User.find(#post.user_id).username %> says <%= link_to topic.subject, [#board, topic] %></b><br />
Try <% #post = topic.posts.limit(1) %>
I've installed devise for my rails app, i can go to the sign in page or the sign up page. But I want them both on a welcome page...
So I've made a welcome_page_controller.rb with the following function:
class WelcomePageController < ApplicationController
def index
render :template => '/devise/sessions/new'
render :template => '/devise/registration/new'
end
end
But when i go to the welcome page i get this error:
NameError in Welcome_page#index
Showing /Users/tboeree/Dropbox/rails_projects/rebasev4/app/views/devise/sessions/new.html.erb where line #5 raised:
undefined local variable or method `resource' for #<#<Class:0x104931c>:0x102749c>
Extracted source (around line #5):
2: <% #header_title = "Login" %>
3:
4:
5: <%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
6: <p><%= f.label :email %><br />
7: <%= f.email_field :email %></p>
8:
Does anybody knows a solution for this problem? Thanks in advance!
Does it have to do with the fact that it is missing the resource function? in the welcome_page controller? It's probably somewhere in the devise controller...?
Regards,
Thijs
Here's how I managed to did it.
I've put a sign up form in my home#index
My files:
view/home/index.html.erb
<%= render :file => 'registrations/new' %>
helper/home_helper.rb
module HomeHelper
def resource_name
:user
end
def resource
#resource = session[:subscription] || User.new
end
def devise_mapping
#devise_mapping ||= Devise.mappings[:user]
end
def devise_error_messages!
return "" if resource.errors.empty?
messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
sentence = I18n.t("errors.messages.not_saved",
:count => resource.errors.count,
:resource => resource_name)
html = <<-HTML
<div id="error_explanation">
<h2>#{sentence}</h2>
<ul>#{messages}</ul>
</div>
HTML
html.html_safe
end
end
You need that part because Devise works with something called resource and it should be defined so you can call your registration#new anywhere.
Like that, you should be able to register. However, I needed to display errors on the same page. Here's what I added:
layout/home.html.erb (the layout used by index view)
<% flash.each do |name, msg| %>
# New code (allow for flash elements to be arrays)
<% if msg.class == Array %>
<% msg.each do |message| %>
<%= content_tag :div, message, :id => "flash_#{name}" %>
<% end %>
<% else %>
# old code
<%= content_tag :div, msg, :id => "flash_#{name}" %>
<% end %> #don't forget the extra end
<% end %>
I found this code here
And here's something I created: I saved my resource object if invalid in a session so that the user hasn't to fill every field again. I guess a better solution exists but it works and it's enough for me ;)
controller/registration_controller.rb
def create
build_resource
if resource.save
if resource.active_for_authentication?
# We delete the session created by an incomplete subscription if it exists.
if !session[:subscription].nil?
session[:subscription] = nil
end
set_flash_message :notice, :signed_up if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => redirect_location(resource_name, resource)
else
set_flash_message :notice, :inactive_signed_up, :reason => resource.inactive_message.to_s if is_navigational_format?
expire_session_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords(resource)
# Solution for displaying Devise errors on the homepage found on:
# https://stackoverflow.com/questions/4101641/rails-devise-handling-devise-error-messages
flash[:notice] = flash[:notice].to_a.concat resource.errors.full_messages
# We store the invalid object in session so the user hasn't to fill every fields again.
# The session is deleted if the subscription becomes valid.
session[:subscription] = resource
redirect_to root_path #Set the path you want here
end
end
I think I didn't forget any code. Feel free to use whatever you need.
Also, you can add your sign in form in the same page (something like that:)
<%= form_for("user", :url => user_session_path) do |f| %>
<%= f.text_field :email %>
<%= f.password_field :password %>
<%= f.submit 'Sign in' %>
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
<%= link_to "Forgot your password?", new_password_path('user') %>
<% end %>
Cheers !
It use to work great under rails 2 and now moving to rails 3 as caused my code to have errors.
Error Message:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each
Slice of code:
<div id="archive-list">
<h4>Archives</h4>
<ul>
<% #archive_list.each do |item| -%>
<li><%= link_to(item[0], archive_url(:year => item[1], :month => item[2])) %></li>
<% end -%>
</ul>
there seems to be an issue with:
<% #archive_list.each do |item| -%>
with this line above
Any help would be great?
#archive_list is probably nil
do a puts #archive_list in the controller before rendering the view and check if it's nil
in the view you could do a <% if #archive_list.exists? %> before iterating over it, if it's an active record relation, or <% if #archive_list.blank? %> if it's something else (from the looks of the code it's the latter).