Rails 4: what is wrong with this method? - ruby-on-rails

I'm upgrading an application to Rails 4 and I cannot for the life of me figure out what is wrong with this method. The offender's the update method:
def update
respond_to do |format|
if #doc.articles.find_index { |a| a.changed? }
#doc.publications.destroy_all
end
if #doc.update_attributes(params[:doc])
#doc.create_activity :update, owner: current_user
if current_user.brand.editable? && params[:editing]
format.html { redirect_to editing_url(#doc) }
else
format.html { redirect_to share_url(#doc.user.ftp, #doc) }
end
end
end
end
Clicking submit generates this error:
ActionController::UnknownFormat in DocsController#update
and highlights this line:
respond_to do |format|
The create method works fine, it looks like this:
def create
#doc = Doc.new(params[:doc])
respond_to do |format|
if #doc.save
#doc.create_activity :create, owner: current_user
if current_user.brand.editable? && params[:editing]
format.html { redirect_to doc_editing_url(#doc) }
else
format.html { redirect_to share_url(#doc.user.ftp, #doc) }
end
else
format.html { render action: "new" }
end
end
end
Any thoughts at all? I'm totally stuck.
Oh, I've got this private method as a before_action too, so it's not that:
private
def set_document
#doc = Doc.find(params[:id])
end
EDIT
I found this quasi-explanation:
In Rails 4.0, ActionController::UnknownFormat is raised when the
action doesn't handle the request format. By default, the exception is
handled by responding with 406 Not Acceptable, but you can override
that now. In Rails 3, 406 Not Acceptable was always returned. No
overrides.
which makes me think it's something to do with routes, but my routes should be default if I've declared them like so, yes?
resources :docs, :except => [:new, :show] do
get "adjust/:state" => "docs#adjust", :as => :adjust
patch "editing" => "docs#editing", :as => :editing
patch "reupdate/" => "docs#reupdate", :as => :reupdate
get "pdf" => "docs#pdf", :as => :pdf
collection { post :sort }
end
EDIT 2
Adding the JSON to the controller, i.e.:
format.html { redirect_to share_url(#doc.user.ftp, #doc) }
format.json { render action: 'share', status: :created, location: #doc }
gives me a no method error and seems to redirect me back to the edit page:
Showing .../fin/app/views/docs/_form.html.erb where line #19 raised:
undefined method `covers?' for nil:NilClass
Really no idea what's going on here.

One possible reason can be that if #doc.update_attributes(params[:doc]) returns false there is no format block being executed in the update method.
Usually you are rendering the edit action in that case.

If you are only serving HTML then you don't need respond_to and format.html at all.

Related

No route matches {:action=>"show", :controller=>"controller_name"}

I'm always getting this error and I don't understand where I am wrong. I think I have everything I need action in controller, resources in route file and view for controller action. I put the route current_events/new in the browser when I get this error. I also try with just resources :current_events
output of rake routes:
current_events GET /current_events(.:format) current_events#index
new_current_event GET /current_events/new(.:format) current_events#new
current_event GET /current_events/:id(.:format) current_events#show
config/routes.rb:
appname::Application.routes.draw do
devise_for :users, controllers: { omniauth_callbacks: "omniauth_callbacks"}
resources :current_events, only: [:show, :new, :index]
end
CurrentEventsController:
class CurrentEventsController < ApplicationController
def index
#current_event = CurrentEvent.all
respond_to do |format|
format.html
format.json { render json: #current_event }
end
end
def create
#current_event = CurrentEvent.new(params[:current_event])
respond_to do |format|
if #current_event.save
format.html { redirect_to #current_event, notice: 'current event was created.' }
format.json { render json: #current_event, status: :created, location: #current_event }
else
format.html { render action: "new" }
format.json {render json: #current_event.errors, status: :unprocessable_entity}
end
end
end
def new
#current_event = CurrentEvent.new
respond_to do |format|
format.html
format.json { render json: #current_event }
end
end
def edit
#current_event = CurrentEvent.find(params[:id])
end
def destroy
#current_event = CurrentEvent.find(params[:id])
#current_event.destroy
respond_to do |format|
format.html { redirect_to current_event_url}
format.json { head :no_content }
end
end
def show
#current_event = CurrentEvent.find(params[:id])
respond_to do |format|
format.html
format.json{ render json: #current_event}
end
end
end
I forgot to say, I am trying to go to new page so in browser I say current_events/new
It will still throw an error if there's a link that doesn't work on the page.
In your view, the link should look something like this:
<%= link_to "name of current event", current_event_path(#current_event) %>
update
based on your rake routes
current_event GET /current_events/:id(.:format) #note ":id"
when you're trying to see a specific current event, you need to pass it an :id which makes sense - if you're trying to call a specific person you need to use their telephone number. so your code should look like this:
<%= link_to 'Back', current_event_path(#event) %>
But keep in the mind that #event won't work unless you define it correctly in the controller action for this view.

respond_with - How to respond with a text

I'm using the respond_to and respond_with in a rails app, but in one use case I need to respond with just a text for just one of the resource formats (:json)... But I can't find how to do this...
I want something like this (I know this doesn't work)
def create
...
respond_with(:json, render :text => "Successfully Done!")
end
Any Idea??
Thanks!
It seems that this may be what you are looking for:
def create
respond_to do |format|
format.html
format.json { render :text => "Successfully Done!" }
end
end
Andres,
The solution is this:
class TextController < ApplicationController
respond_to :json, :text
def index
respond_with do |format|
format.json {
render :text => "I'm a text provided by json format"
}
format.text {
render :text => "I'm a text"
}
end
end
end
And at your routes.rb:
match '/text' => 'text#index', defaults: { format: 'text' }

Ruby on rails(routing error)

Hi Can any body resolve this error as I am getting NoMethodError for my prop_manager_controller.rb
NoMethodError in PropManagerController#new
undefined method `prop_manager?' for #<User:0x471f690>
controllr
class PropManagerController < ApplicationController
before_filter :login_required, :except => [:new, :create]
load_and_authorize_resource
# GET /prop_manager
# GET /prop_manager.json
def index
#prop_managers= PropManager.order('id:desc').page(params[:page])
respond_to do |format|
format.html #index.html.erb
format.json {render json: #prop_managers}
end
end
# GET /prop_manager
# GET /prop_manager.json
def show
#prop_managers= PropManager.order('id:desc').page(params[:page])
respond_to do |format|
format.html #show.html.erb
format.json {render json:#prop_managers}
end
end
# GET /prop_manager
#GET /prop_manager.json
def new
#prop_managers= PropManager.new
respond_to do |format|
format.html #new.html.erb
format.json {render json:#prop_managers}
end
end
# GET /prop_manager/1/edit
def edit
#prop_manager = PropManager.find(params[:id])
end
# POST /prop_managers
# POST /prop_managers.json
def create
#prop_manager = PropManager.new(params[:prop_manager])
respond_to do |format|
if #prop_manager.save
#UserMailer.delay.homeowner_welcome_email(#home_owner, params[:home_owner][:password])
UserMailer.propmanager_welcome_email(#prop_manager, params[:prop_manager][:password]).deliver
format.html { redirect_to prop_manager_path(#prop_manager), notice: 'PropManager was successfully created.' }
format.json { render json: #prop_manager, status: :created, location: #prop_manager }
else
#prop_manager.errors[:base] << #exception_message
format.html { render "new" }
format.json { render json: #prop_manager.errors, status: :unprocessable_entity }
end
end
end
# PUT /prop_manager/1
# PUT /prop_manager/1.json
def update
#prop_manager = PropManager.find(params[:id])
#prop_manager.card_validity = nil
begin
customer = Stripe::Customer.retrieve(#prop_manager.stripe_customer_id)
customer.email = params[:prop_manager][:email]
customer.card = { :number => params[:prop_manager][:credit_card_number],
:exp_month => params[:prop_manager][:credit_card_expiry_month],
:exp_year => params[:prop_manager][:credit_card_expiry_year],
:cvc => params[:prop_manager][:credit_card_cvc_code],
:name => params[:prop_manager][:credit_card_holder_name] }
customer.save
#prop_manager.card_validity = true
rescue => exception
#exception_message = exception.message
end
respond_to do |format|
if #prop_manager.update_attributes(params[:prop_manager])
format.html { redirect_to home_owner_path(#prop_manager), notice: 'PropManager account details updated successfully.' }
format.json { head :ok }
else
#prop_manager.errors[:base] << #exception_message
format.html { render action: "edit" }
format.json { render json: #prop_manager.errors, status: :unprocessable_entity }
end
end
end
# DELETE /home_owners/1
# DELETE /home_owners/1.json
def destroy
#prop_manager = PropManager.find(params[:id])
begin
customer = Stripe::Customer.retrieve(#prop_manager.stripe_customer_id)
customer.delete
rescue => exception
# Do nothing - there is no customer record in the stripe account
end
#prop_manager.destroy
respond_to do |format|
format.html { redirect_to prop_managers_url }
format.json { head :ok }
end
end
end
routes
GEMS::Application.routes.draw do
resources :customer_feedbacks
resources :general_repairs_prices
resources :steam_cleaning_prices
resources :window_cleaning_prices
resources :roof_cleaning_prices
resources :gutter_cleaning_prices
resources :residential_jobs do
member do
get 'accept'
get 'decline'
get 'print_friendly'
end
collection do
post 'create_job_with_estimate'
put 'update_multiple'
end
resources :residential_job_changes do
member do
get 'approve'
end
end
end
resources :home_owners
resources :prop_managers
resources :contractors do
member do
get 'approve'
get 'disapprove'
end
end
resources :users
resources :email_templates
resources :feedback_survey_questions
resources :decline_reasons
resources :services
resources :branches
resources :sessions
resources :password_resets
get "sites/index"
get "sites/about_us"
get "sites/home_owner"
get "sites/home_owner_front"
get "sites/prop_manager"
get "sites/owner_register"
get "login" => "sessions#new", :as => "login"
get "logout" => "sessions#destroy", :as => "logout"
end
I think I have already defined the route correctly so Please let me know any changes require.
It looks like either:
Your User model does not have the method prop_manager? on it. This is a method you'd have to add on your own -- active record on its own would not make a method available with a ? on it available.
From the look of the trace it's possible this is happening in a call back on the user model. Is there anything like that in your User model?
OR -
You're using cancan I noticed. It may be possible that the permissions of the user that's logged in do not include accessing that method -- though I'd think that cancan would provide a better error than simply saying the method is not available.

undefined method `save' for nil:NilClass

I get this error when trying to register a new user.
NoMethodError (undefined method save' for nil:NilClass):
app/controllers/users_controller.rb:49:increate'
app/controllers/users_controller.rb:48:in `create'
class UsersController < ApplicationController
before_filter :require_no_user, :only => [:new, :create]
before_filter :require_user, :only => [:show, :edit, :update]
#filter_resource_access
def index
#users = User.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #users }
end
end
def show
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #user }
end
end
def new
##user = User.new
#carriers = Carrier.find(:all)
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #user }
end
end
def edit
end
def create
#user = User.new(params[:user])
if #user.save
flash[:notice] = "Account registered!"
redirect_back_or_default account_url
else
render :action => :new
end
end
def profile
#user = User.find(params[:id])
end
def update
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to(#user, :notice => 'User was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
end
end
end
def destroy
#user = User.find(params[:id])
#user.destroy
respond_to do |format|
format.html { redirect_to(users_url) }
format.xml { head :ok }
end
end
def delete
#user = User.find(params[:user_id])
#user.destroy
redirect_to :users
end
end
without seeing your view code, its hard to say, but since you have commented out the #user object that is sent to the new view, perhaps the params coming back from the view are not defined as key value pairs from the form as user attributes?
The error is happening because the #user variable is nil, so calling (nil).save will fail. This means that User.new(params[:user]) is returning nil, which should never happen. User.new should always return a record, even if it is invalid.
So, since the controller looks pretty ordinary, I'll take a shot in the dark and suggest checking your User model for a 'new' method. You might be overriding ActiveRecord's 'new' method with some logic that returns nil and breaks your controller. If so, you must replace 'def new' with a different method name.
If that doesn't help, please provide us with the code in your User model.

How do I set up my #product=Product.find(params[:id]) to have a product_url?

Trying to recreate { script/generate scaffold }, and I've gotten thru a number of Rails basics. I suspect that I need to configure default product url somewhere. But where do I do this?
Setup:
Have: def edit { #product=Product.find(params[:id]) }
Have edit.html.erb, with an edit form posting to action => :create
Have def create { ... }, with the code redirect_to(#product, ...)
Getting error: undefined method `product_url' for #< ProductsController:0x56102b0>
My def update:
def update
#product = Product.find(params[:id])
respond_to do |format|
if #product.update_attributes(params[:product])
format.html { redirect_to(#product, :notice => 'Product was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #product.errors, :status => :unprocessable_entity }
end
end
end
Ah, add in /config/routes.rb the line:
map.resources :products
and make sure you put that above the default:
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
This defines a system for giving :product's urls.

Resources