undefined method `total_pages' for #<Array:0x1041df24> - ruby-on-rails-3

I am trying to paginate an array but not able to do so. Please help
Below is my controller code:
require 'will_paginate/array'
class AccountsController < ApplicationController
def children
#account = #rest_resource
#children = []
User.find_all_by_parentId(#account.user.id).paginate(:page
=> params[:page], :per_page => 10).each { |eu|
u = eu.user
ent = Table2.find(u.login)
#children << ent unless ent.nil?
}
end
end
View File -> children.html.erb:
<%= will_paginate #children %>
<table>
<%= render :partial => 'account', :collection => #children %>
</table>
Partial View ->_account.html.erb:
<tr class="<%= cycle('even', 'odd') %> <% if account.user.is_test? %>Test<% end %>">
<td><strong><%= link_to h(account.login), account_path(account) %></strong></td>
<td><% if account.user.test? %>Test <% end %><%= account.attr2 %></td>
<td>
<strong><%= account.companyName %></strong><br/>
<%= account.contact %> - <%= account.Email %> - <%= account.Mobile %>
</td>
<td><%=h account.Status %></td>
</tr>
This is not working. It says:
undefined method `total_pages' for #<Array:0x1041df24>
Rails version:
Rails 3.2.13
JRuby Version:
jruby 9.1.17.0 (2.3.3)
My app is using:
will_paginate (3.0.4)
Please could someone help on this

You are initializing #children as an array and you are passing the same to will_paginate so its throwing an error...try passing like
will_paginate #children[0]
if you wanna pass each and every instance in that array use
#children.each
method

Related

Rails delete action is not being run, and renders 200 OK

I am having trouble implementing the DELETE action on any object that I have for my application.
To show you the general code for my delete action in the Group Controller:
def destroy
#group = Group.find(params[:id])
respond_to do |format|
if #group.delete
format.html { redirect_to group_path }
format.json { head :no_content }
else
format.html { redirect_to group_path }
format.json { head :no_content }
end
end
end
And the code for my View layout:
<h1>My Groups</h1>
<table>
<tr>
<th>Name</th>
<th>Users</th>
<th></th>
<th></th>
</tr>
<% #groups.each do |group| %>
<tr>
<td><%= group.name %></td>
<td>
<% group.memberships.each do |membership| %>
<%= User.find(membership.user_id).name %>
<br/>
<% end %>
</td>
<td><%= link_to 'Show', group %></td>
<td><%= link_to 'Destroy', group, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Group', new_group_path %>
I am unable to delete the group object even though the rails server log gives me back a 200 OK response. The returned page is a blank screen:
Started DELETE "/groups/2" for 127.0.0.1 at 2013-03-19 01:22:01 +0800
Processing by GroupsController#destroy as HTML
Parameters: {"authenticity_token"=>"aH+z0DlL7NeoVlxda8Td76WdnrH7/G8UyWDqbJcTu9w=", "id"=>"2"}
Completed 200 OK in 0ms (ActiveRecord: 0.0ms)
ActiveRecord wasn't used and there were no changes to the database. There were no such problems in the past, but I only realized that I could not delete any kind of object recently.
I have been trying to find solutions to similar problems found on the net, but unfortunately it seems like no one has had this problem yet.
Update 1:
The following is my application layout:
<!DOCTYPE html>
<html>
<head>
<%= csrf_meta_tag %>
<title>Home</title>
<%= javascript_include_tag :application %>
<%= stylesheet_link_tag :application, :media => "all" %>
<%= javascript_include_tag "/javascripts/main.js" %>
<%= stylesheet_link_tag "/css/main.css" %>
</head>
<body>
<%= yield %>
</body>
</html>
But when I use the console to delete the object. It works:
1.9.3-p194 :003 > Group.find(23).delete
Group Load (0.5ms) SELECT "groups".* FROM "groups" WHERE "groups"."id" = $1 LIMIT 1 [["id", 23]]
SQL (3.0ms) DELETE FROM "groups" WHERE "groups"."id" = 23
=> #<Group id: 23, name: "groupie", created_at: "2013-03-18 15:29:42", updated_at: "2013-03-18 15:29:42", user_id: nil>
I just found the solution to the question. I actually wrote a code for an around_filter that messed up the destroy session for every controller:
around_filter :clear_registration_id_on_destroy_session, only: :destroy
def clear_registration_id_on_destroy_session
is_filter_active = (controller_path == 'devise/sessions' && params[:action] == 'destroy')
if is_filter_active && user_signed_in?
if current_user.update_attribute(:device_platform, nil)
logger.info "Updated device platform attributes to nil"
end
if current_user.update_attribute(:registration_id, nil)
logger.info "Updated registration id attributes to nil"
end
yield
end
end
The problem is that I didn't yield anything for any other controller other than devise:sessions#destroy.
So for those who are as forgetful as me, please remember to think about the other conditions when is_filter_active is not true.
def clear_registration_id_on_destroy_session
is_filter_active = (controller_path == 'devise/sessions' && params[:action] == 'destroy')
if is_filter_active && user_signed_in?
if current_user.update_attribute(:device_platform, nil)
logger.info "Updated device platform attributes to nil"
end
if current_user.update_attribute(:registration_id, nil)
logger.info "Updated registration id attributes to nil"
end
yield
else
yield
end
end
It sounds like your delete link is just acting as a link to the show action, as the method option is not being picked up.
You need to have the appropriate javascript included in your application layout, as the delete link requires JS to use the correct HTTP method.
If you are using Rails >= 3.1 make sure you have the following in the header of the layout file you are using for rendering the page:
<%= javascript_include_tag :application %>
Also make sure you have the csrf_meta_tag in your layout:
<%= csrf_meta_tag %>

nested resources with form_for losing first id

This is a strange error that has really got me bugged. First, some background.
I have the following nested resources in my config/routes.rb:
scope :requirements => { :protocol => 'https' } do
resource :user
resources :orgs do
resources :members
resources :events
resources :levels
resources :attendances
end
resources :sessions, :only => [:new, :create, :destroy]
end
Then, in app/controllers/levels_controller.rb I have:
def edit
#org = Org.find(params[:org_id])
#level = OrgLevel.find(params[:id])
end
def update
#level = OrgLevel.find(params[:id])
if #level.update_attributes(params[:level])
flash[:success] = "Level details updated"
redirect_to #level
else
render 'edit'
end
end
Finally, in app/views/levels/edit.html.erb, I have:
<% provide(:title, "Edit #{#level.name} for #{#org.name}") %>
<div class="hero-unit">
<h2>Edit "<%= #level.name %>" membership level for <%= #org.name %></h2>
<div class="row">
<div class="span6 offset3">
<%= form_for [#org, #level], :url => org_level_path do |f| %>
<%= render 'shared/error_messages' %>
<table class="editor">
<tr>
<td class="label_x">
<%= f.label :name %>
</td>
<td colspan="3">
<%= f.text_field :name %>
</td>
</tr>
</table>
<% end %>
</div>
</div>
</div>
The result of calling https://spot-macbook.local/orgs/55/levels/162/edit is normal, but clicking "Save Changes" results in a redirection to https://spot-macbook.local/orgs/162/levels/162 and the following error:
ActiveRecord::RecordNotFound in LevelsController#show
Couldn't find Org with id=162
Rails.root: /Users/ogod/Projects/rails_projects/nom_de_joye_app
Application Trace | Framework Trace | Full Trace
app/controllers/levels_controller.rb:71:in `correct_user'
Request
Parameters:
{"requirements"=>{"protocol"=>"https"},
"org_id"=>"162",
"id"=>"162"}
Note that the org_id has changed to "162" instead of "55". What am I doing wrong?
Doh!
Five seconds after I post this question, I realised there error and corrected it.
The original has the update method with the following:
redirect_to #level
This should be:
redirect_to org_level_path(#org, #level)
Such a simple error, but I was looking in the wrong place!

No Method Error for "comments", can't find and correct the nil value to make the comment post

I'm relatively new to rails and am trying to pull off my first polymorphic association with comments.
I am running rails 3.2.3
Edit - When I try to post a comment, my log is returning this error:
Started POST "/comments" for 127.0.0.1 at 2012-05-20 13:17:38 -0700
Processing by CommentsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"SOLcF71+WpfNLtpBFpz2qOZVaqcVCHL2AVZWwM2w0C4=", "comment"=>{"text"=>"Test this comment"}, "commit"=>"Create Comment"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = 101 LIMIT 1
Completed 500 Internal Server Error in 126ms
NoMethodError (undefined method `Comment' for nil:NilClass):
app/controllers/comments_controller.rb:13:in `create'
I have tried out many different solutions offered on SO and elsewhere, including the answer from Jordan below, due, I'm sure, to my own inexperience, but have been unable to resolve the error.
The trace calls out line 13 in the Comments Controller and I commented after that line below to mark the error:
class CommentsController < ApplicationController
def index
#commentable = find_commentable
#comments = #commentable.comments
end
def new
#post = Post.find(params[:post_id])
end
def create
#commentable = find_commentable
#comment = #commentable.comments.build(params[:comment]) #<<<<LINE 13
if #comment.save
flash[:notice] = "Successfully created comment."
redirect_to :id => nil
else
render :action => 'new'
end
end
private
def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
end
Posts Controller:
def show
#post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render :json => #post }
end
end
Comment template (in post show)
<ul id="comments">
<% if #comments %>
<h2>Comments</h2>
<% #comments.each do |comment| %>
<li><%= comment.text %></li>
<% end %>
<% else %>
<h2>Comment:</h2>
<% end %>
</ul>
<%= simple_form_for [#commentable,Comment.new], :html => { :class => 'form-horizontal', :multipart => true } do |f| %>
<fieldset>
<%= f.input :text %>
Upload Photo <%= f.file_field :photo %>
</fieldset>
<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
</div>
<% end %>
Post show:
<p id="notice"><%= notice %></p>
<div class="row">
<div class="span2 offset1">
<%= image_tag #post.photo.url(:show) %>
</div>
<div class="span5">
<h1><%= #post.title %></h1>
<p><%= #post.index_text.html_safe %></p>
<p><%= #post.show_text.html_safe %></p>
<%= render "comments/comment" %>
<%= render "comments/form" %>
<% if can? :update, #course %>
<%= link_to 'Edit Post', edit_post_path(#post), :class => 'btn btn-mini' %>
<%= link_to 'Delete Post', #post,
confirm: 'Are you sure?',
method: :delete,
:class => 'btn btn-mini' %>
<%= link_to 'New Post', new_post_path, :class => 'btn btn-mini' %>
<% end %>
</div>
<nav class="span2 offset1">
<ul class="well">
<li>Category 1</li>
<li>Category 2</li>
</ul>
</nav>
</div>
<div class="row offset2">
<%= link_to 'Back to Posts', posts_path, :class => 'btn btn-mini' %>
</div>
Routes:
resources :posts, :has_many => :comments
resources :comments
It is probably something obvious that someone with more experience can resolve. Let me know if anything comes to mind. Brian
The problem is that #commentable is nil, which means that CommentsController#find_commentable is returning nil. I think your regular expression is sound, so that means one of two things is happening in find_commentable:
There aren't any keys in params that match your regex.
Your regex is matching but there aren't any records in the resulting table with the id in value.
Debug this as usual by inspecting params and the records in your database to make sure they look like you expect them to look.
The problem is your find_commentable method.
Here are the params passed to your CommentsController#create:
Started POST "/comments" for 127.0.0.1 at 2012-05-20 13:17:38 -0700
Processing by CommentsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"SOLcF71+WpfNLtpBFpz2qOZVaqcVCHL2AVZWwM2w0C4=", "comment"=>{"text"=>"Test this comment"}, "commit"=>"Create Comment"}
Here is your CommentsController#create:
def create
#commentable = find_commentable
#comment = #commentable.comments.build(params[:comment]) #<<<<LINE 13
def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
As you can see, find_commentable expects a param like xx_id (for example, comments_id) which it uses to search for an appropriate class (in case of comments_id, it will be Comment), otherwise it returns nil. Refer classify and constantize here.
Your params do not contain any such param. So, you always get a nil object.
Your find_commentable needs some rework. I think in case of nested_fields, it should be an expression like
/(.+)_attributes$/
instead of
/(.+)_id$/.
And you need to have
:accepts_nested_attributes_for :commentable
in your Comment model class.
I tried both of the above answers, but the problem continued.
I ended up consulting with a friend who suggested the following solution, which I like because it's more elegant than my original attempt and easier to read (for later, when I or someone else need to return to the code):
def find_commentable
if params[:post_id]
Post.find(params[:post_id])
#elsif params[:other_id]
# Other.find(params[:other_id])
else
# error out?
end
end
The commented out section will refer to other associations once I get them up and running.

Why is Rails displaying memory addresses on my page?

My view:
<h1><%= #territory.name %></h1>
<%= link_to 'List of Territories', territories_path %>
<%= render 'shared/address_form' %>
<table>
<tr>
<td><strong>Name</strong></td>
<td><strong>Street</strong></td>
<td><strong>District</strong></td>
<td><strong>Note</strong></td>
<tr>
<%= #addresses.each do |address| %>
<tr>
<td><%= address.name %></td>
<td><%= address.street %></td>
<td><%= address.district %></td>
<td><%= address.note %></td>
</tr>
<% end %>
</table>
The form I render here is:
<%= form_for [#territory, #new_address] do |f| %>
<div>
<p>
<%= f.label :address %><br />
<%= f.text_area :address %>
</p>
</div>
<div class='file-wrapper'>
<%= f.submit "Submit" %>
</div>
<% end %>
Here is the territories controller, where the instance variable addresses is defined:
class TerritoriesController < ApplicationController
def index
#territories = Territory.all
end
def show
#territory = Territory.find(params[:id])
#new_address = #territory.addresses.build
#addresses = #territory.addresses
end
.
.
.
Why is Rails displaying
#<Address:0x7e088224>#<Address:0x7e0881d4>#<Address:0x7e088134>#<Address:0x7e088094># <Address:0x7e087ff4>#<Address:0x7e087f54>#<Address:0x7e087eb4>#<Address:0x7e087e14>#<Address:0x7e087d74>#<Address:0x7e0bce48>
after the form and before the table?
Thanks
Thomas
Check your layouts (app/views/layouts/*). Most likely you have included some ERB code in the one that is being rendered with this page that displays these addresses. Is that the full code of your view?
Edit: I found your solution. Right now, you have <%= #addresses.each ... %>. The each method runs the block on all elements, and then returns the list of elements. You do not want this code to be displayed. Remove the = so that <%= is just <%
You have some view code somewhere (in a layout or a view helper) that is implicitly calling the to_s method of your Address model instances. Look for something like <%= #address %>.
As you have seen, the non-overridden behaviour of the to_s method is to output the memory address of the object instance.
Those are not memory addresses. Those are instances of your Address class. If you'd override the to_s method in that class, you'd see that output there instead. And the reason you see those object printed out is your use of <%=. Changing this line
<%= #addresses.each do |address| %>
to this
<% #addresses.each do |address| %>
should fix it.
First: I can see no form in your view.
Second: Your view looks ok.
Have a look at your layout files.

rails 3 form throws undefined method `model_name'

userhome_controller:
def edit_reviewer_email
#user = User.find(params[:id])
end
edit_reviewer_email:
<div class="pagetop center">
<%= form_for #user, update_reviewer_email_userhome_path(#user) do |f| %>
<%= f.label :email %><br />
<%= f.text_field :email, :size => 1 %>
<%= f.submit %>
<% end %>
</div>
error:
undefined method `stringify_keys' for "/userhome/18/update_reviewer_email":String
Should i be using form_tag when the model is accessed via a different controller?
I am looking for a rails 3 tutorial that covers a variety of forms if you know of any.
Thanks!
Your controller needs to limit its request to a single record (you can just use find):
#user = User.find(params[:id])
Or if you want to stick with a where statement:
#user = User.where("id = ?", params[:id]).first