简体   繁体   中英

Rails: respond_with custom object

respond_with is acatually meant to use with ActiveModel 's instances. I tried to use it with OpenStruct 's instance, but it raises an error. Is that ever possible to use respond_with with custom objects?

class CryptController < ApplicationController
  respond_to :json

  def my_action
    respond_with OpenStruct.new(foo: 'foo', bar: 'bar')
  end
  # ...
end

Raises: **undefined method persisted?' for nil:NilClass** ruby-2.1.4@rails4/gems/actionpack-4.2.5.1/lib/action_dispatch/routing/polymorphic_routes.rb:298:in persisted?' for nil:NilClass** ruby-2.1.4@rails4/gems/actionpack-4.2.5.1/lib/action_dispatch/routing/polymorphic_routes.rb:298:in handle_list' /home/workstat/.rvm/gems/ruby-2.1.4@rails4/gems/actionpack-4.2.5.1/lib/action_dispatch/routing/polymorphic_routes.rb:206:in polymorphic_method' /home/workstat/.rvm/gems/ruby-2.1.4@rails4/gems/actionpack-4.2.5.1/lib/action_dispatch/routing/polymorphic_routes.rb:114:in polymorphic_url'

respond_with is a helper method that exposes a resource to mime requests.

From the documentation

 respond_with(@user)

for the create action, is equivalent (assuming respond_to :xml in the example) to:

respond_to do |format|
    if @user.save
      format.html { redirect_to(@user) }
      format.xml { render xml: @user, status: :created, location: @user }
    else
      format.html { render action: "new" }
      format.xml { render xml: @user.errors, status: :unprocessable_entity }
    end
  end
end

The precise equivalent is dependent upon the controller action.

The key takeaway is that respond_with takes a @instance variable as an argument and first attempts to redirect to the corresponding html view. Failing that, it renders an xml response, in the case above.

You are passing in an ostruct, which doesn't correspond to an instance of your model. In this case, respond_with doesn't know where to redirect to in your views and doesn't have an instance from which to render a mime response.

See this RailsCast and this blogpost from José Valim.

A note: The error undefined method persisted? is generated by Devise and probably because it can't find a route.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM