I don't understand why I'm getting this error message when I run RSpec:
Failure/Error: post :create
ActionController::RoutingError:
No route matches {:controller=>"stocks", :action=>"create"}
The controller stocks exists, the action create exists, and the route it should be using is this:
match 'stocks/:user_id' => 'stocks#create', :via => :post, :as => :query
Route File:
FruthScreener::Application.routes.draw do
root :to => 'stocks#index' # add user_id
match 'stocks/:user_id' => 'stocks#create', :via => :post, :as => :query
match 'stocks/:user_id' => 'stocks#destroy', :via => :delete, :as => :reset
match 'stocks/:user_id/update' => "stocks#update_index", :via => :post
Stock Controller: (Yes, this will be DRYed up)
class StocksController < ApplicationController
def index
#user = User.create
#user_id_num = #user.id
#user.stocks = Stock.all
#user.save
selected_user_stocks = (UserStock.where("user_id = #{#user_id_num} AND selected = true")).take(25)
#stocks = UserStock.convert_to_stocks(selected_user_stocks)
#pages = Pagination.determine_num_pages(#user.stocks)
end
def update_index
#user_id_num = params[:user_id]
#user = User.find(#user_id_num)
selected_user_stocks = UserStock.where("user_id = #{#user_id_num} AND selected = true")
#stocks = UserStock.convert_to_stocks(selected_user_stocks)
#pages = Pagination.determine_num_pages(#stocks)
#stocks = Stock.display(#stocks, params[:pageNumber].to_i)
render partial: 'stock_data'
end
def create
UserStock.eliminate_stocks(params) # thinking it's like "creating" a new batch of stocks
#user_id_num = params[:user_id]
#user = User.find(#user_id_num)
selected_user_stocks = UserStock.where("user_id = #{#user_id_num} AND selected = true")
#stocks = UserStock.convert_to_stocks(selected_user_stocks)
#pages = Pagination.determine_num_pages(#stocks)
#stocks = Stock.display(#stocks, 1)
render partial: 'stock_data'
end
def destroy
stocks_to_reset = UserStock.where("user_id = #{params[:user_id]}")
stocks_to_reset.each do |user_stock|
user_stock.selected = true
user_stock.save
end
#user_id_num = params[:user_id]
#user = User.find(#user_id_num)
selected_user_stocks = UserStock.where("user_id = #{#user_id_num} AND selected = true")
#stocks = UserStock.convert_to_stocks(selected_user_stocks)
#pages = Pagination.determine_num_pages(#stocks)
#stocks = Stock.display(#stocks, 1)
render partial: 'stock_data'
end
end
Stock Controller Spec: (test at bottom is failing)
require 'spec_helper'
RSpec.configure do |config|
config.infer_spec_type_from_file_location!
end
describe StocksController do
context "index" do
before do
#user_count = User.all.count
#stock_count = Stock.all.count
get :index
end
it "should create a new user" do
expect(User.all.count).to eq(#user_count + 1)
end
it "should associate all stocks with the user" do
expect(User.last.stocks.count).to eq(#stock_count)
end
end
context "create" do # investigate why this isn't working...
it "should render the stock_list partial" do
user = User.create
post :create
response.should render_template(partial: "stock_list")
end
end
end
Thanks!!
match 'stocks/:user_id' => 'stocks#create', :via => :post, :as => :query
tells us that it needs :user_id to be a valid route.
post :create
has no :user_id... so it doesn't refer to a valid route.
I'd change it to
post :create, :user_id => user.id
post :create, params: {user_id: user.id}
Related
all,
I tried this:
<h9>Thursday</h9>
<% #thursday.each do |chorelist| %><br>
<p2><%= chorelist.name %></p2>
<%= button_to "delete", chorelists_destroy_path(:id, chorelist.id) %>
<% end %>
It won't do the trick, however.
As you can see, I am trying to add a delete button with each iteration. What am I missing here?
I'm still new to Rails, so any help will be most appreciated.
Addendum: I received this error message when using that latter method:
"Couldn't find Chorelist with 'id'={:name=>"Sweep Floors", :day=>"Sunday", :user_id=>2}"
I checked the console, and those parameters are all there.
class SaveListController < ApplicationController
before_filter :authenticate_user!
def index
#chorelist = Chorelist.create(user_id: params[:user_id], chore_id: params[:chore_id], day: params[:day], name: params[:chore_name])
redirect_to pick_chores_path
end
def display
#chorelist = Chorelist.all
#monday = #chorelist.where("day = 'Monday'", user_id: current_user.id)
#tuesday = #chorelist.where("day = 'Tuesday'", user_id: current_user.id)
#wednesday = #chorelist.where("day = 'Wednesday'", user_id: current_user.id)
#thursday = #chorelist.where("day = 'Thursday'", user_id: current_user.id)
#friday = #chorelist.where("day = 'Friday'", user_id: current_user.id)
#saturday = #chorelist.where("day = 'Saturday'", user_id: current_user.id)
#sunday = #chorelist.where("day = 'Sunday'", user_id: current_user.id)
end
def destroy
#chorelist = Chorelist.find(id: params[:id])
#chorelist.destroy
redirect_to show_chores_path
end
end
Rails.application.routes.draw do
resources :chorelists
get 'about' => 'welcome#about'
get 'contact' => 'welcome#contact'
root 'welcome#index'
get 'about' => 'welcome#about'
get 'pick_chores' => 'pick_chores#index'
post 'save_list' => 'save_list#index'
get 'show_chores' => 'save_list#display'
post 'chorelists_destroy' => 'save_list#destroy'
resources :chores
devise_for :users
end
Change :id, chorelist.id to id: chorelist.id
<h9>Thursday</h9>
<% #thursday.each do |chorelist| %><br>
<p2><%= chorelist.name %></p2>
<%= button_to "delete", chorelists_destroy_path(id: chorelist.id) %>
<% end %>
On controller
def destroy
#chorelist = Chorelist.find(params[:id])
#chorelist.destroy
# do your things
end
I'm having problems with the Podio_rails_sample. I've included my leadsController and leads.rb files. The line that gets hung up is field['config']['settings']['allowed_values'].
Line 25 is the problematic one:
NoMethodError in LeadsController#new
undefined method `[]' for nil:NilClass
Extracted source (around line #25):
23 app = Podio::Application.find(APP_ID)
24 field = app.fields.find { |field| field['external_id'] == 'status' }
25 field['config']['settings']['allowed_values']
26 end
27
28 def self.create_from_params(params)
Rails.root: c:/Sites/podio_rails_sample
app = Podio::Application.find(APP_ID)
field = app.fields.find { |field| field['external_id'] == 'status' }
field['config']['settings']['allowed_values']
end
def self.create_from_params(params)
Rails.root: c:/Sites/podio_rails_sample
-----------------------------------
class LeadsController < ApplicationController
before_filter :load_collections, :only => [:new, :edit]
def index
#leads = Lead.all
end
def new
#lead = Lead.new
end
def create
Lead.create_from_params(params['lead'])
redirect_to leads_path, :notice => 'Lead created'
end
def edit
#lead = Lead.find_basic(params[:id])
end
def update
Lead.update_from_params(params[:id], params['lead'])
redirect_to leads_path, :notice => 'Lead updated'
end
def destroy
Lead.delete(params[:id])
redirect_to leads_path, :notice => 'Lead deleted'
end
#protected
def load_collections
#lead_contacts = Lead.space_contacts
#sales_contacts = Lead.users
#statuses = Lead.statuses
end
end
-------------------------------------
- leads.rb file
class Lead < Podio::Item
APP_ID =12328033
SPACE_ID =3204114
# Find all items in the Leads app
def self.all
collection = self.find_all(APP_ID)
collection[:all]
end
# Find valid lead contacts in the space
def self.space_contacts
Podio::Contact.find_all_for_space(SPACE_ID, :order => 'contact', :limit => 12, :contact_type => 'space,connection', :exclude_self => false) rescue []
end
# Find valid sales contacts in the space
def self.users
Podio::Contact.find_all_for_space(SPACE_ID, :order => 'contact', :limit => 12, :contact_type => 'user', :exclude_self => false) rescue []
end
# Find valid statuses
def self.statuses
app = Podio::Application.find(APP_ID)
field = app.fields.find { |field| field['external_id'] == 'status' }
field['config']['settings']['allowed_values']
end
def self.create_from_params(params)
# raise fields.inspect
self.create(APP_ID, { :fields => fields_from_params(params) })
end
def self.update_from_params(id, params)
self.update(id, { :fields => fields_from_params(params) })
end
#
# Map the field values return by the Podio API to simple getters
#
def organization
field_values_by_external_id('company-or-organisation', :simple => true)
end
def lead_contact
field_values_by_external_id('contacts', :simple => true).try(:[], 'name')
end
def sales_contact
field_values_by_external_id('sales-contact', :simple => true).try(:[], 'name')
end
def potential_revenue_value
field_values_by_external_id('potential-revenue').try(:first).try(:[], 'value').to_i
end
def potential_revenue_currency
field_values_by_external_id('potential-revenue').try(:first).try(:[], 'currency')
end
def probability
field_values_by_external_id('probability-of-sale', :simple => true)
end
def status
field_values_by_external_id('status', :simple => true)
end
def followup_at
field_values_by_external_id('next-follow-up').try(:first).try(:[], 'start').try(:to_datetime)
end
protected
def field_values_by_external_id(external_id, options = {})
if self.fields.present?
field = self.fields.find { |field| field['external_id'] == external_id }
if field
values = field['values']
if options[:simple]
values.first['value']
else
values
end
else
nil
end
else
nil
end
end
def self.fields_from_params(params)
{
'company-or-organisation' => params[:organization],
'contacts' => (params[:lead_contact].present? ? params[:lead_contact].to_i : nil),
'sales-contact' => (params[:sales_contact].present? ? params[:sales_contact].to_i : nil),
'potential-revenue' => { :value => params['potential_revenue_value'], :currency => params['potential_revenue_currency'] },
'probability-of-sale' => params[:probability].to_i,
'status' => params[:status],
'next-follow-up' => DateTime.new(params['followup_at(1i)'].to_i, params['followup_at(2i)'].to_i, params['followup_at(3i)'].to_i).to_s(:db)
}.delete_if { |k, v| v.nil? }
end
end
I'm working on an application where I've had to put together some custom rails parameters for the routes and I keep getting no route found errors when I try to access the page associated with the show method. The application is allowing me to reach my edit pages, so I know it's working on some level but I have to have an error I'm not seeing somewhere that's messing with the normal view. The custom parameters rely on an :identifier that has been custom created for each object. Because the application manages several institutions, all with their objects and files, I've had to right several different sets of routes to handle each different thing. The routes for institutions seem to be working fine, but the second set, for :intellectual_objects are the ones that aren't working.
This is my routes file (irrelevant parts excluded):
Fluctus::Application.routes.draw do
get "institutions/:institution_identifier/objects", to: 'intellectual_objects#index', as: :institution_intellectual_objects, :constraints => { :institution_identifier => /[\w+\.]+/ }
post "institutions/:institution_identifier/objects", to: 'intellectual_objects#create', :constraints => { :institution_identifier => /[\w+\.]+/ }
#Intellectual Object Routes
#get "objects/:institution_identifier", to: 'intellectual_objects#index', as: :institution_intellectual_objects, :constraints => { :institution_identifier => /[\w+\.]+/ }
#post "objects/:institution_identifier", to: 'intellectual_objects#create', :constraints => { :institution_identifier => /[\w+\.]+/ }
patch "objects/:intellectual_object_identifier", to: 'intellectual_objects#update', :constraints => { :intellectual_object_identifier => /[\w+\/\.]+/ }
put "objects/:intellectual_object_identifier", to: 'intellectual_objects#update', :constraints => { :intellectual_object_identifier => /[\w+\/\.]+/ }
delete "objects/:intellectual_object_identifier", to: 'intellectual_objects#destroy', :constraints => { :intellectual_object_identifier => /[\w+\/\.]+/ }
get "objects/:intellectual_object_identifier/edit", to: 'intellectual_objects#edit', as: :edit_intellectual_object, :constraints => { :intellectual_object_identifier => /[\w+\/\.]+/ }
get "objects/:intellectual_object_identifier/events", to: 'events#index', as: :intellectual_object_events, :constraints => { :intellectual_object_identifier => /[\w+\/\.]+/ }
post "objects/:intellectual_object_identifier/events", to: 'events#create', :constraints => { :intellectual_object_identifier => /[\w+\/\.]+/ }
get "objects/:intellectual_object_identifier", to: 'intellectual_objects#show', as: :intellectual_object, :constraints => { :intellectual_object_identifier => /[\w+\/\.]+/ }
#post "objects/institution_identifier/:intellectual_object_identifier/data", to: 'generic_files#create', as: intellectual_object_generic_files, :constraints => { [:intellectual_object_identifier, :institution_identifier] => /[\w+\.]/ }
#patch "objects/institution_identifier/:intellectual_object_identifier/data/:filename", to: 'generic_files#update', :constraints => { [:intellectual_object_identifier, :institution_identifier] => /[\w+\.]/ }
Blacklight.add_routes(self)
mount Hydra::RoleManagement::Engine => '/'
root :to => "catalog#index"
end
This is my IntellectualObject Controller:
class IntellectualObjectsController < ApplicationController
before_filter :authenticate_user!
#load_and_authorize_resource :institution, only: [:index, :create]
load_and_authorize_resource :through => :institution, only: :create
#load_and_authorize_resource except: [:index, :create]
before_filter :set_object, only: [:show, :edit, :update, :destroy]
before_filter :set_institution, only: [:index, :create]
include Aptrust::GatedSearch
apply_catalog_search_params
include RecordsControllerBehavior
self.solr_search_params_logic += [:for_selected_institution]
def update
if params[:counter]
# They are just updating the search counter
search_session[:counter] = params[:counter]
redirect_to :action => "show", :status => 303
else
# They are updating a record. Use the method defined in RecordsControllerBehavior
super
end
end
def destroy
resource.soft_delete
respond_to do |format|
format.json { head :no_content }
format.html {
flash[:notice] = "Delete job has been queued for object: #{resource.title}"
redirect_to root_path
}
end
end
protected
# Override Hydra-editor to redirect to an alternate location after create
def redirect_after_update
intellectual_object_path(resource)
end
def self.cancan_resource_class
CanCan::ControllerResource
end
private
def for_selected_institution(solr_parameters, user_parameters)
#puts "In for_selected_institution------------------------------------------"
#puts params[:institution_identifier]
#puts params[:intellectual_object_identifier]
if(params[:institution_identifier])
institution = Institution.where(desc_metadata__institution_identifier_tesim: params[:institution_identifier]).first
else
io = IntellectualObject.where(desc_metadata__intellectual_object_identifier_tesim: params[:intellectual_object_identifier]).first
institution = io.institution
end
#puts "INSTITUTION: #{institution.id}"
solr_parameters[:fq] ||= []
solr_parameters[:fq] << ActiveFedora::SolrService.construct_query_for_rel(is_part_of: "info:fedora/#{institution.id}")
end
# Override Blacklight so that it has the "institution_identifier" set even when we're on a show page (e.g. /objects/foo:123)
def search_action_url options = {}
institution_intellectual_objects_path(params[:institution_identifier] || #intellectual_object.institution.institution_identifier)
end
def set_institution
if params[:institution_identifier].nil? || Institution.where(desc_metadata__institution_identifier_tesim: params[:institution_identifier]).empty?
redirect_to root_url
flash[:alert] = "Sonething wrong with institution_identifier."
else
#institution = Institution.where(desc_metadata__institution_identifier_tesim: params[:institution_identifier]).first
authorize! [:create, :index], #institution if cannot? :read, #institution
end
end
def set_object
if params[:intellectual_object_identifier].nil? || IntellectualObject.where(desc_metadata__intellectual_object_identifier_tesim: params[:intellectual_object_identifier]).empty?
redirect_to root_url
flash[:alert] = "Something wrong with intellectual_object_identifier."
else
io_options = IntellectualObject.where(desc_metadata__intellectual_object_identifier_tesim: params[:intellectual_object_identifier])
io_options.each do |io|
if params[:intellectual_object_identifier] == io.intellectual_object_identifier
#intellectual_object = io
#institution = #intellectual_object.institution
end
end
if #intellectual_object.nil?
redirect_to root_url
flash[:alert] = "The object you requested does not exist."
end
#authorize! [:show, :edit, :update, :destroy], #institution if cannot? :read, #institution
end
end
end
I'm getting the following error when I try to access the show route (for example: localhost:3000/objects/test.org/126939282):
ActionController::UrlGenerationError in IntellectualObjects#show
Showing /Users/kec6en/HydraApp/fluctus/app/views/intellectual_objects/_facet_limit.html.erb where line #11 raised:
No route matches {:action=>"index", :intellectual_object_identifier=>"columbia.edu/798d6e812041532c", :controller=>"intellectual_objects", :f=>{"institution_name_ssi"=>["Columbia University"]}}
The parameters are showing:
{"intellectual_object_identifier"=>"columbia.edu/798d6e812041532c"}
And I'm getting this error when I run my spec tests on the IntellectualObjectController
Failure/Error: get :show, intellectual_object_identifier: obj1
ActionController::UrlGenerationError:
No route matches {:intellectual_object_identifier=>"kaulkedurgan.org13/39b1eb47-da8b-4145-b03b-5f1851407012", :controller=>"intellectual_objects", :action=>"show"}
I just don't understand because the routes are there, and some of them appear to be working in the application, but every single one is failing in my spec tests. Any and all help is appreciated. Thank you.
Your route to intellectual_objects#index has the constraint that the :institution_identifier should match /[\w+\.]+/, but columbia.edu/798d6e812041532c does not match that regexp. Even when you add \/ to your regexp, I am pretty sure that the slash will confuse Rails routing system.
Perhaps you want to change the route to something like this
get "institutions/:institution_identifier/:some_id/objects",
to: 'intellectual_objects#index',
as: :institution_intellectual_objects,
constraints: { institution_identifier: /[\w+\.]+/ }
And than provide columbia.edu (institution_identifier) and 798d6e812041532c (some_id) as separate values.
According to your error:
No route matches {:action=>"index"
It seems you're trying to access the index action?
Being honest, I couldn't bring myself to look through all your routes (you may want to cut out the irrelevant stuff?)
How are you calling the routes with link_to?
How to redirect the two links to two urls by using single method in controller?
Example:
def index
#location_id = Location.find(#location_id)
#epc = Enr::Rds::CurrentEpc.find_by_location_id(#location_id)
if # PDF EPC link clicked
#epc.current_epc_path[-4..-1] == '.pdf'
content = open(#epc.current_epc_path, "rb") {|io| io.read }
send_data content, :filename => 'epc.pdf', :disposition => 'inline'
end
if # LIVE EPC link clicked
#epc = Enr::Rds::XmlData.find_by_location_id(#location_id)
redirect_to #epc.report_url
end
end
in my view,
<%= link_to 'PDF', enr_location_current_epc_index_path(#location) %>
<%= link_to 'LIVE', enr_location_current_epc_index_path(#location) %>
in my routes
resources :current_epc, only: [:index, :show] do
get :download, :on => :collection
end
I would consider create 2 differente actions. One for each case. It would make your actions and your code much easier to read.
Then u would result with 3 actions. Index which would only load the initial objects, one to treat the specific id by the first logic and another link to treat the second logic.
def index
#location_id = Location.find(#location_id)
#epc = Enr::Rds::CurrentEpc.find_by_location_id(#location_id)
end
pdf_epc
#location_id = Location.find(#location_id)
#epc = Enr::Rds::CurrentEpc.find_by_location_id(#location_id)
#epc.current_epc_path[-4..-1] == '.pdf'
content = open(#epc.current_epc_path, "rb") {|io| io.read }
send_data content, :filename => 'epc.pdf', :disposition => 'inline'
end
def live_epc
#epc = Enr::Rds::XmlData.find_by_location_id(#location_id)
redirect_to #epc.report_url
end
in your routes
resources :current_epc, only: [:index, :show] do
get :download, :on => :collection
end
get "/pdf_epc/:id" => "current_epc#pdf_epc", :as => enr_location_current_epc_pdf
get "/live_epc/:id" => "current_epc#live_epc", :as => enr_location_current_live_epc
in your view
<%= link_to 'PDF', enr_location_current_epc_pdf_path(#location) %>
<%= link_to 'LIVE', enr_location_current_live_epc_path(#location) %>
def pdf_url
if (params[:url] == 1)
do something
else
do something else
end
#epc = Enr::Rds::CurrentEpc.find_by_location_id(#location_id)
if #epc != nil
#epc.current_epc_path[-4..-1] == '.pdf'
content = open(#epc.current_epc_path, "rb") {|io| io.read }
send_data content, :filename => 'epc.pdf', :disposition => 'inline'
end
end
In your routes.rb:
match "/anything/pdf_url/:url" => "anything#pdf_url"
And your two links:
<%= link_to "first", "/anything/pdf_url/1" %>
<%= link_to "second", "/anything/pdf_url/2" %>
EDIT:
member is used when it requires an :id parameter, if not it is a collection. Anyway, I would use match in that case like (which is in parenthesis is optional):
match "/anything(/download/:url)" => "anything#index"
and get the parameter in your controller like this:
def index
if params[:url] == 1 # Or whatever you put in your link_to
# redirect_to url
else
# redirect_to url
end
end
EDIT 2:
Index controller:
def index
if params[:id]
#location_id = Location.find(params[:id])
#epc = Enr::Rds::CurrentEpc.find_by_location_id(#location_id)
if params[:url] == 'pdf'
#epc.current_epc_path[-4..-1] == '.pdf'
content = open(#epc.current_epc_path, "rb") {|io| io.read }
send_data content, :filename => 'epc.pdf', :disposition => 'inline'
elsif params[:url] == 'live'
#epc = Enr::Rds::XmlData.find_by_location_id(#location_id)
redirect_to #epc.report_url
end
else
#locations = Location.all
respond_to do |format|
format.html
format.json { render :json => #locations }
end
end
end
Your routes:
match "/anything(/:id(/:url))" => "anything#index"
Your view (change links to fit your tastes, it's just a simple example):
<%= link_to "first", "/anything/1/pdf" %>
<%= link_to "second", "/anything/1/live" %>
I have a model which is linking to the show method:
<%= link_to "View Others", :controller => "browse",
:action => "show", :id => #id, :d => "25" %>
Clicking the link gives:
http://localhost:3000/browse/santa-cruz?d=25
Rails gives the error though:
No route matches {:controller=>"browse", :action=>"show", :id=>nil, :d=>"25"}
If I take the extra parameter off everything works.
<%= link_to "View Others", :controller => "browse",
:action => "show", :id => #id %>
Goes to http://localhost:3000/browse/santa-cruz
This page loads and I am getting the correct params[:id]
Any ideas?
Pasted bellow is the show for my controller
def show
if params[:d].nil? then
# Show list of addresses in city.
addresses = Address.where(:slug => params[:id])
profile = []
addresses.each do |ad|
profile << ad.profile
end
unless profile.blank?
#profile = Kaminari.paginate_array(profile).page(params[:page]).per(5)
#title = "Profiles Near " + addresses.first.city
#id = params[:id]
else
redirect_to :controller => 'pages', :action => 'notlaunched', :zip => params[:id]
end
else # :d exists
# show all within :d miles.
addresses = Address.where(:slug => params[:id])
nearby = Address.near("#{addresses.first.fulladdress}", params[:d], :order => :distance)
profiles = nearby.map{ |ad| ad.profile }.uniq
end
end
Here's the Index:
def index
cities = []
states = []
Address.find_each do |ad|
cities << { :city => ad.city, :slug => ad.slug } # slug becomes the :id of show
states << ad.state
end
#cities = cities.uniq
#states = states.uniq
#title = "Browse Cities"
end