Rails - paginate - ruby

Is this how will_paginate is used? The example in their documentation doesn't demonstrate result of a sql query.
I installed included the gem in the gem file, restarted without any errors. but still not working.
def list_items
#list = Item.find(:all, :select => 'status', :conditions => { :status => ["New"]} )
#list_page = #list.paginate(:per_page => 10)
respond_to do |format|
format.html { render :partial => 'item_list'}
format.js
end
end
NoMethodError (undefined method `paginate' for #<Array:0x97bd3fc>):

https://github.com/mislav/will_paginate/wiki/Backwards-incompatibility
You need to add require 'will_paginate/array'

Related

Routes. Rails 3

I update apllication from rails 2 to rails 3.
And I rewrite routes with resources. How to write route to this actions:
def delete_attachment
#object = Article.find(params[:id])
attachment = Attachment.find(params['attachment_id'])
attachment.attachment = nil
attachment.destroy
redirect_to :action => 'edit', :id => #object.id
end
def edit_attachment
#object = Article.find(params[:id])
attachment = Attachment.find(params['attachment_id'])
attachment.title = params['attachment_title']
attachment.description = params['attachment_description']
attachment.save
redirect_to :action => 'edit', :id => #object.id
end
def add_attachment
#object = Article.find(params[:id])
attachment = Attachment.new
attachment.attachment = params['attachment_file']
attachment.title = params['attachment_title']
attachment.description = params['attachment_description']
attachment.article_id = #object.id
attachment.save
params['attachment_title'] = nil
params['attachment_description'] = nil
redirect_to :action => 'edit', :id => #object.id
end
This is right solution?
resources :articles do
delete '/articles/delete_attachment', :to => 'articles#delete_attachment'
put '/articles/edit_attachment', :to => 'articles#edit_attachment'
post '/articles/add_attachment', :to => 'articles#add_attachment'
end
I have no way to check it on the server, because there are still many incompatibilities.
You can change the routes to:
resources :articles do
member do
delete 'delete_attachment'
put 'edit_attachment'
post 'add_attachment'
end
end
If you don't have multiple member routes, you can also pass :on to a route, eliminating the block:
Like,
resources :photos do
get 'preview', on: :member
end

Add surrounding XML tag on XML response?

Is there an easy way to wrap the XML response of a controller action into something like <response>#model.to_xml</response> without creating an extra response model?
The respond_with looks something like:
respond_with(#model, :status => :accepted, :location => nil) do |format|
format.xml { render :xml => #model.to_xml(:dasherize => false) }
end
respond_with(#model, :status => :accepted, :location => nil) do |format|
format.xml {
render :xml => {:response => #model}.to_xml(:dasherize => false)
}
end

Rails form validation works in one template but not another for the same Model

Another hair-puller. AFter two days of fighting with this I cannot figure out what is wrong here.
Basically I have a form validation triggered by the model:
validates :user, :presence => true, :uniqueness => true
validates :email, :presence => true, :uniqueness => true, :on => :create
validates :passwordHash, :presence => true, :confirmation => true, :on => :create
The user not being empty works on the update form View:
= simple_form_for #user do |f|
= f.input :user
= f.input :locale
= f.input :localeLanguage, :label => 'Language', :as => :select, :collection => $language_array
= f.input :moderator
= f.input :email
= f.input :passwordHash, :label => 'Password'
But not on the new users View:
= simple_form_for #user do |f|
%table.table-condensed
%tr
%td
=f.input :user, :label => false, :placeholder => 'username'
%tr
%td
= f.input :passwordHash, :label => false, :placeholder => 'password'
%tr
%td
= f.input :email, :label => false, :placeholder => 'email'
%tr
%td
= f.submit "Create User", :class => 'btn btn-primary'
The only difference I can see between these views is that the first one has sessions created since a user has already logged in, the second one doesn't. But as far as I know this should not make a difference. Of course, the update form does have an actual #user object whereas in the new one it is empty. But I've seen Ryan Bates' railscast of a new user validation and he does pretty much the same thing.
What happens is the users#create action being invoked after submitting the form with empty values (which should not be possible). Of course I get an error because the passwordHash is empty.
I should point out that I'm not using any extra gems to aid in password confirmation (in the railscast, Bates uses bcrypt but I can't use it because we create the password hash a different way plus I think that's for the password confirmation magic only). In any case this should not affect the form validation should it?
Any theories or ideas are welcome here, I'm going crazy. I'm about to write some crappy javascript to do it by hand which would be awful and would probably take me a week, I don't do javascript ;)
Thanks.
Edit
Per Rachid's request, here are the new and create actions:
def new
#user = User.new
end
def create
#failsafe for failing form validation
unless params[:passwordHash].present?
redirect_to new_user_path, :notice => 'User or password cannot be blank'
else
password_and_salt = User.hash_password(params[:passwordHash])
hashed_password = password_and_salt[:password]
user_salt = password_and_salt[:salt]
#user = User.new(:user => params[:user], :passwordHash => hashed_password, :salt => user_salt)
if #user.save
session[:user_id] = #user.id
redirect_to session[:item_to_edit]
else
redirect_to new_user_path, :notice => "User already exists, please pick another one"
end
end
end
Edit 2
I've rewritten the create method based on the first answer, but still getting an error:
def create
respond_to do |format|
if params[:passwordHash].present? && params[:user].present?
password_and_salt = User.hash_password(params[:passwordHash])
hashed_password = password_and_salt[:password]
user_salt = password_and_salt[:salt]
#user = User.new(:user => params[:user], :passwordHash => hashed_password, :salt => user_salt, :online_user => 1 )
if #user.save
session[:user_id] = #user.id
redirect_to session[:item_to_edit]
else
format.html { render :action => "new" }
format.json { render :json => #user.errors, :status => :unprocessable_entity }
end
else
format.html { render :action => "new" }
format.json { render :json => #user.errors, :status => :unprocessable_entity }
end
end
end
The error is undefined method 'model_name' for NilClass:Class for this line:
= simple_form_for #user do |f|
Obviously the #user = User.new is not making it back to the form. At this point I'm a little confused as to how I should write the create method for it to work properly and show the error messages. But I feel I'm closer :)
#misha, here is the update controller action, it's just pretty standard scaffolding:
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(params[:user])
if session[:return_to]
format.html { redirect_to session[:return_to], :notice => 'User was successfully updated.' }
else
format.html { redirect_to users_path, :notice => 'User was successfully updated.' }
end
format.json { head :ok }
else
format.html { render :action => "edit" }
format.json { render :json => #user.errors, :status => :unprocessable_entity }
end
end
end
First of all what you assume here is incorrect:
What happens is the users#create action being invoked after submitting
the form with empty values (which should not be possible). Of course I
get an error because the passwordHash is empty.
It is possible that users#create is invoked and actually it should happen. It is in the create action where you handle this stuff. I think your problem is the fact that you do a redirect if the #user is not saved. You should render the view again, so the error messages can be displayed.
So instead of:
redirect_to new_user_path, :notice => "User already exists, please pick another one"
Try:
render :action => 'new'
Edit based on your comment:
When validation fails Rails populates #user.errors automatically. You don't have to do anything in the controller (i.e. your create action)! All you have to do is display the errors in #user.errors in your view.
About the error you are getting now:
The reason you are getting the error is that #user is not set. You have to rewrite your create method to something like this:
def create
respond_to do |format|
if params[:user][:passwordHash].present?
password_and_salt = User.hash_password(params[:user][:passwordHash])
hashed_password = password_and_salt[:password]
user_salt = password_and_salt[:salt]
end
#user = User.new(params[:user].merge({:passwordHash => hashed_password, :salt => user_salt, :online_user => 1}))
if #user.save
session[:user_id] = #user.id
redirect_to session[:item_to_edit]
else
format.html { render :action => "new" }
format.json { render :json => #user.errors, :status => :unprocessable_entity }
end
end
end

best_in_place gem to edit currency

I'm using the best_in_place gem to edit balances:
index.html.erb:
<%= best_in_place bankaccount, :balance, :display_with => :number_to_currency %>
but after editing, I get a unformatted number ($45 changed to 46 shows as 46).
How do I get best_in_place to display the new value as $$$?
controller:
respond_to :html, :json
...
def update
#bankaccount = Bankaccount.find(params[:id])
if #bankaccount.update_attributes(params[:bankaccount])
respond_with #bankaccount
else
render :json => #bankaccount.errors.full_messages, :status => :unprocessable_entity
end
# if #bankaccount.update_attributes(params[:bankaccount])
# redirect_to #bankaccount, :notice => "Successfully updated bankaccount."
# else
# render :action => 'edit'
# end
end
This thread is already answered but I tried the accepted answer and it didn't work.
However using a lambda everything is nice again. Rails 4, by the way.
<%= best_in_place #text, :body, :type => :textarea, :display_with => lambda{ |v| markdown(v) }, :html_attrs => { :class => 'edit-text-body' } %>
Ended up using BIP's :display_as => :mk_bal with mk_bal defined in model Bankaccount as:
def mk_bal
ActionController::Base.helpers.number_to_currency(self.balance, :precision => 2)
end

Undefined method 'title' for nil:NilClass

I am following railsspace book but when i trying edit show and eliminate a post owner (chapter 15) I get: error message
undefined method `title' for nil:NilClass
follow extact:
1: <div class="post">
2: <div class="post_title">
3:
4: <%= sanitize post.title %>
5: <% unless hide_edit_links? %>
6: <span style="float:right">
7: <%= link_to_unless_current 'Mostrar', blog_post_path(post.blog, post) %> |
Ruby 1.9.2
Rails 3.1.3
The controller, views and routes is as follow:
Controller: posts_controller
# Encoding: UTF-8
class PostsController < ApplicationController
helper :profile
before_filter :protect, :protect_blog
# GET /posts
# GET /posts.xml
def index
#Recheck implement paginate for Rails 3.1.3
##pages, #posts = paginate(#blog.posts)
#posts = #blog.posts
#title = "Administración del Blog"
respond_to do |format|
format.html # index.rhtml
format.xml { render :xml => #posts.to_xml }
end
end
# GET /posts/1
# GET /posts/1.xml
def show
#post = Post.find(params[:id])
#title = #post.title
respond_to do |format|
format.html # show.rhtml
format.xml { render :xml => #post.to_xml }
end
end
# GET /posts/new
def new
#post = Post.new
#title = "Nuevo post"
end
# GET /posts/1;edit
def edit
#post = Post.find(params[:id])
#title = "Edit #{#post.title}"
end
# POST /posts
# POST /posts.xml
def create
#post = Post.new(params[:post])
#post.blog = #blog
respond_to do |format|
if #post.duplicate? or #blog.posts << #post
flash[:notice] = 'Post was successfully created.'
format.html { redirect_to blog_post_url(:id => #post) }
format.xml { head :created, :location => blog_post_url(:id => #post) }
else
format.html { render :action => "new" }
format.xml { render :xml => #post.errors.to_xml }
end
end
end
# PUT /posts/1
# PUT /posts/1.xml
def update
#post = Post.find(params[:id])
respond_to do |format|
if #post.update_attributes(params[:post])
flash[:notice] = 'Post was successfully updated.'
format.html { redirect_to post_url(:id => #post) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #post.errors.to_xml }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.xml
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
format.xml { head :ok }
end
end
private
# Ensure that user is blog owner, and create #blog.
def protect_blog
#blog = Blog.find(params[:blog_id])
user = User.find(session[:user_id])
unless #blog.user == user
flash[:notice] = "That isn't your blog!"
redirect_to hub_url
return false
end
end
end
View: index
<h2>Sus Blog Posts</h2>
<p class="edit_link">
<%= link_to 'Agregar nuevo post', new_blog_post_path %>
<%= "| Pages: #{pagination_links(#pages)}" if paginated? %>
</p>
<%= render :partial => "post", :collection => #posts %>
View: post
<div class="post">
<div class="post_title">
<%= sanitize post.title %>
<% unless hide_edit_links? %>
<span style="float:right">
<%= link_to_unless_current 'Mostrar', blog_post_path(post.blog, post) %> |
<%= link_to_unless_current 'Editar', edit_blog_post_path(post.blog, post) %> |
<%= link_to 'Eliminar', blog_post_path(post.blog, post),
:confirm => 'Deseas eliminar este post?', :method => :delete %>
</span>
<% end %>
</div>
<div class="post_body"><%= sanitize post.body %></div>
<div class="post_creation_date">
Publicado <%= time_ago_in_words post.created_at %> ago
<% if post.updated_at != post.created_at %>
<br /> Modified <%= time_ago_in_words post.updated_at %> ago
<% end %>
</div>
</div>
In this view , i has triying put # in the variable post =#post, but it not work
Routes
Expression::Application.routes.draw do
get "email/remind"
get "avatar/index"
get "avatar/upload"
get "avatar/delete"
get "community/index"
get "community/browse"
get "community/search"
get "faq/index"
get "faq/edit"
get "spec/index"
get "spec/edit"
get "profile/index"
get "profile/show"
get "user/index"
get "user/register"
get "site/index"
get "site/about"
get "site/help"
get "user/login"
get "user/logout"
get "user/edit"
get "user_mailer/welcome_email"
post "user/register"
post "user/login"
post "user/edit"
post "spec/edit"
post "faq/edit"
post "community/index"
post "community/search"
post "avatar/upload"
post "email/remind"
resources :blogs do
resources :posts
end
# The priority is based upon order of creation:
# first created -> highest priority.
# Sample of regular route:
# match 'products/:id' => 'catalog#view'
# Keep in mind you can assign values other than :controller and :action
# Sample of named route:
# match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
# This route can be invoked with purchase_url(:id => product.id)
# Sample resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Sample resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Sample resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Sample resource route with more complex sub-resources
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', :on => :collection
# end
# end
# Sample resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
# root :to => 'welcome#index'
root :to => 'site#index'
# match'', :controller => 'site', :action => 'index', :id => nil
resources :user
match '/register', :to => 'user#register'
match '/about', :to => 'user#about'
match '/help', :to => 'user#help'
match '/login', :to =>'user#login'
match '/edit', :to =>'user#edit'
match '/user/welcome_email', :to => 'user#create'
#resources :profile
#match '/show', :to => 'profile#show'
# Install the default route as the lowest priority.
match ':controller/:action/:id'
match 'profile', :to => 'profile#show', :as => "profile"
match 'hub', :to => 'user#index', :as => 'hub'
##Change Route pagina 343
# You can have the root of your site routed by hooking up ''
# -- just remember to delete public/index.html.
match '', :controller => 'site', :action => 'index', :id => nil
###
#match'', :controller => 'user', :action => 'about', :id => nil
#match'', :controller => 'user', :action => 'help', :id => nil
# See how all your routes lay out with "rake routes"
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id(.:format)))'
end
ApplicationStacktrace
app/views/posts/_post.erb:4:in `_app_views_posts__post_erb__1793130860277527745_40556500'
app/views/posts/show.html.erb:3:in `_app_views_posts_show_html_erb__2356198700875868089_40643800'
app/controllers/posts_controller.rb:23:in `show
Use #post.title, instead of post.title on line 4 of your template.
After deleting your code is trying to redirect to posts_url.
However I do not see that in your routes. btw you can also do rake routes at the command line to see what your routes are.
I think you need to add a get for posts/index although I would really look to try and use RESTful routing which would clean up much of your routes.

Resources