Rails - find_by_* route - ruby-on-rails-3

In products_controller.rb
# GET /search/'brand'
def brand
#product = Product.find_all_by_brand(params[:brand])
respond_to do |format|
format.html # brand.html.erb
end
end
In routes.rb
match '/search/:brand' => 'products#brand'
If I try accessing localhost:3000/search/Apple I get the following error Couldn't find Product with id=Apple
Is there anything that I'm missing? Are there any other files that I should handle?
Update
Now I'm getting undefined method 'size' for nil:NilClass and I'm not even sure what I changed.
The query executed by rails is select "products".* FROM "products" WHERE "products"."brand" = 'Apple' ORDER BY last_seen DESC and they seem to return the correct products.
Application Trace
app/views/products/_product.html.erb:1:in
_app_views_products__product_html_erb___2255278_29707176'
app/views/products/brand.html.erb:1:in
_app_views_products_brand_html_erb___464952485_38589588'
app/controllers/products_controller.rb:52:in `brand'

The comments in your controller indicate that you might want to try /search/brand/Apple.

Found the error, the erb page was receiving product instead of products. Typing error.

Related

sunspot_solr - NoMethodError (undefined method `result=' for nil:NilClass)

I have a problem related to the use of sunspot_solr. I have an application that performs some searches using this gem. There are 5 models that has this feature, only 1 of them is showing an error in
#search.results
NoMethodError (undefined method `result=' for nil:NilClass):
app/controllers/financial_dashboards_controller.rb:27:in `index'
Here is my code:
Controller
#search = Sunspot.search(Purchase) do
fulltext params[:search]
with(:product_owner).equal_to(current_user.id)
facet(:status)
if params[:status].present?
with(:status).equal_to(params[:status])
end
facet(:sell_date)
if params[:sell_date].present?
with(:sell_date).equal_to(params[:sell_date])
end
order_by(:sell_date, :desc)
end
#line 27
#sales = #search.results.paginate(:page => params[:page], :per_page => 5)
Model (Purchase):
searchable do
text :product_name
text :product_short_description
integer :product_owner
string :status
string :sell_date
end
def product_name
product.name
end
def product_short_description
product.short_description
end
def product_owner
product.user.id
end
def sell_date
date.to_s(:year_month)
end
#indicates status of the payment and delivery
def status()
if !self.closed.nil?
I18n.t('purchases.status.finished')
elsif !self.measured.nil?
I18n.t('purchases.status.measured')
elsif !self.accomplished.nil?
I18n.t('purchases.status.delivered')
elsif !self.paid.nil?
I18n.t('purchases.status.paid')
elsif !self.canceled.nil?
I18n.t('purchases.status.canceled')
elsif !self.date.nil?
I18n.t('purchases.status.waiting_payment')
end
end
Another strange thing is that on my development machine, this code works perfectly. On production machine that uses nginx, the code displays this error.
I checked the version of gems and they match. I tried
rake sunspot:solr:reindex RAILS_ENV=production
to reindex. I tried
rake sunspot:solr:stop RAILS_ENV=production
rake sunspot:solr:start RAILS_ENV=production
to restart the search server. Even tried to remove solr/ folder and let the start script copy it again.
And why the other models work perfectly? Any ideas how to solve this?
Thanks
In my case, it was a situation when the key field (id) was not unique.
It happened because I have designed a mysql view with non distinct id field.
And that is why sunspot always "dropped" first hit to nil during next non unique row indexation.
So
hit.result = result
raised an error somewhere in sunspot gem code
When i figured it out (i've spent few hours on it), I just have made my id field unique, reindexed my models and problem have gone.

Rails 3 - named route redirecting to wrong controller action

I'm fairly new to rails, but I have completed a couple of projects before, including the Michael Hartl Tutorial.
I'm building a simple app that stores a virtual wardrobe.
I've got 2 tables - users and items - where a user has_many items and an item belongs_to a user.
I set up the following named route in my routes.rb file:
match "/wardrobe", to: "items#index"
However, when I try to go to /wardrobe in my browser I get a no route match error as follows:
No route matches {:action=>"show", :controller=>"items"}
I'm not sure why rails is trying to route via the show action when I've named the route through the index action.
These are the relevant actions in my ItemsController:
def show
#item = Item.find(params[:id])
end
def index
#items = Item.all
end
The redirect is called on create as follows:
def create
#item = Item.new(params[:item])
if #item.save
flash[:success] = "Item added"
redirect_to wardrobe_path
else
render 'new'
end
end
rake routes provides the following:
wardrobe /wardrobe(.:format) items#index
So, I know the route exists.
Can anyone explain what's going on here? And how I can go about fixing it?
Thanks in advance
It might be because it's rake route is called wardrobe_path rather than wardrobes_path (plural) - when it's singular Rails will default to show action I believe. That might be causing the confusion.

Activeadmin - undefined method `batch_action'?

I'm trying to use activeadmin's batch_action so I can run actions on more than one record. However when trying to run my rails server I get the following error.
undefined method `batch_action' for #<ActiveAdmin::ResourceDSL:0xb11f980> (NoMethodError)
Here is the activeadmin resource code:
ActiveAdmin.register Product do
batch_action :destroy, false
filter :name
index do
selectable_column
column :name
default_actions
end
controller do
def current_company
#current_company
end
end
end
I'm not sure where I'm getting it wrong - I need to show a corresponding checkboxes against the records and then define a batch action. Where am I getting it wrong here?
Got the answer :) was a wrong entry in my gemfile.
https://github.com/gregbell/active_admin/issues/1302

redirect_to from "destroy" to "index"

Problem appears when I want to remove element from paginated table in "ajaxized" way. My tasks controller calls its destroy method in response to [DELETE] /tasks/1234, but at the end I want to redirect to index to get the list automatically refreshed.
Unfortunately, what redirect_to tasks_url at this point does is [DELETE] /tasks request.
Is there any way to force GET request instead of DELETE while redirecting from inside of destroy ?
Use redirect_to with status 303
def destroy
#task = Task.find(params[:id])
#task.destroy
redirect_to :action => :index, status: 303
end
redirect_to documentation says:
http://api.rubyonrails.org/classes/ActionController/Redirecting.html
If you are using XHR requests other than GET or POST and redirecting after the request then some browsers will follow the redirect using the original request method. This may lead to undesirable behavior such as a double DELETE. To work around this you can return a 303 See Other status code which will be followed using a GET request.
Don't use redirect. Use render. Abstract the functionality to get the table data into a library module and then call that from both index as well as the delete methods, and then add then add the render call to the delete method so that the index view is what is sent back in response.
require 'myLibrary'
include myModule
def index
getTableData
end
def destroy
flash.now[:notice] = "Delete operation failed" unless Task.destroy(params[:id])
getTableData
render 'myController/index'
end
in lib/myLibrary
module myModule
def getTableData
# Table Foo here
end
end
Ok, so to sum up this question. The easiest way I found to fix the issue, is to mess a bit in routes.rb by adding: "tasks" => "tasks#index", :via => :get and to use redirect_to tasks_url (in my case) directly in destroy action in controller.
This will solve the problem with kaminari pager as well (which renders strange links in some cases).
I think you should rearrange your code on the client side:
Memorize current page
fire destroy action, await true or false
request index at memorized page using ajax call.
Why not to use :action param ?
def destroy
#task = Task.find(params[:id])
#task.destroy
redirect_to :action => :index
end
You probably don't want to do a standard rails redirect when using ajax. This blog post has some good insight on the issue and solutions. Note this is from a similar question in January, answered by DGM

Rails 3.1 custom controller action keeps asking for ID even when route is specified

I'm trying to add a custom action ('last_five') to a controller.
My routes are specified as:
people_last_five GET /people/last_five(.:format) {:action=>"last_five", :controller=>"people"}
(i.e. that's the output of rake_routes).
But when I browse to /people/last_five I get the following error.
Started GET "/people/last_five" for XXX.XX.XXX.XXX at Sun May 15 22:03:18 +0000 2011
Processing by PeopleController#last_five as HTML
User Load (1.4ms)^[[0m SELECT users.* FROM users WHERE users.id = 3 LIMIT 1
Completed in 86ms
ActiveRecord::RecordNotFound (Couldn't find Person without an ID):
I thought this was a problem in my routes.rb
In my routes.rb I currently have:
get 'people/last_five'
resources :people
I've also tried
resources :people do
get 'last_five', :on => collection
end
but that gives the same results.
Why is rails trying to get an ID when there is no "/:id/" in the route?
This even happens when I specify the route as '/people/:id/last_five' and pass it a dummy id. In that case it still tells me ActiveRecord::RecordNotFound (Couldn't find Person without an ID).
I have this problem even when I reduce the action itself to a stub for debugging, so I don't think that's the problem. In my controller:
# GET /people/last_five
def last_five
logger.info "LAST FIVE IS BEING CALLED"
##people = Person.last_five
#respond_with #people do |format|
# format.json { render :json => #people }
#end
end
Any idea what's going on here? It seems like rails is being told to get an ID by something outside of routes.rb. I've looked everywhere I can think.
Any leads are HIGHLY appreciated.
Thanks.
EDIT:
My PeopleController begins like so:
before_filter :authenticate_user!, :except => []
filter_resource_access
respond_to :html, :js, :json
Per the discussion on your questions, the cause is a before/around filter interfering rather than an issue with your specific action. Your application is searching for a User, so it may be authentication-related.
Are you sure this goes in Control, and not in Model? Rails doesn't want Model stuff in Control.