Rails 3 + Devise 2 + JsonP / Callbacks - ruby-on-rails-3

I'm working on a PhoneGap mobile app that communicates with a rails3 server using a REST api and json. Authentication is done using devise 2.0.4.
For my own controllers I can specify that rails should wrap the json with the callback to handle the Cross-Domain problem by the following:
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #books, :callback => params[:callback] }
end
notice the:
:callback => params[:callback]
I'm unable to do that with the devise controllers.
How can I get devise to respond to js requests - i.e. json with a callback?
Thanks a lot,
Ariel

It would be better to override devise controllers providing the :callback parameter to renderer or using before_filter somehow. In order to do that copy devise controller(s) from github/local-gem-directory to your app and then edit. But it would be much easier to define a JS views for each action:
If you ain't done it already start with generating devise views (which is not necessary but would help you to get the idea):
rails g device:views -s
It would generate lots of *.html.erb files inside of your app/views/devise folder. You have to create appropriate *.js.erb next to them with following contents:
<%=render :inline => params[:callback]+'('+resource.to_json+')'%>
PS: Actually you may just put that line into app/views/application.js.erb and skip other steps;)

Related

Rails 3 with devise undefined method `users_url`

I'm making some small changes to devise in order to overwrite the layout used and some other things so I decided to create my custom routes with controllers. I only added this to the routes so far:
devise_for :users, :controllers => {
:sessions => "sessions/user",
:registrations => "registrations/user"
}
which is supposed to load the login page when accessed by /users/sign_in and it does it very well. When I try to ajax post to that url in order to validate the user input and login I get this error: NoMethodError (undefined method 'users_url' for #<Sessions::UserController:0x000000041bed98>):
The controller is basic and nothing was changed to overwrote devise logic:
class Sessions::UserController < Devise::SessionsController
layout "login" # The only addition. Rest is handled by devise
end
I had this working for a good while but today I decided to use devise for another model (admins) and I generated it's files using the devise command rails generate devise Admin which completely messed my working code of logging in the users.
Any ideas?

Rails Cache Action Won't Expire

I'm on Heroku and trying to implement caching in my Rails app, but I'm running into some problems that I don't understand. I thought it would be easy after reading the Rails Guide and Heroku docs on caching strategies, but apparently doing something wrong.
Issue 1: view of action doesn't seem to expire
Issue 2: when I use :layout => false, both my admin and app layout are used (trying to only get the application layout)
Any help for this newbie would be most appreciated!
production.rb (also installed dalli per heroku documentation)
config.cache_store = :dalli_store
config.action_controller.perform_caching = true (added after reading http://bit.ly/oRKub1)
controller
layout 'admin'
caches_action :show, :layout => false
def show
render :layout => 'application'
end
def update
expire_action :action => :show
end
I tried to test the expiration by changing a product, but the show view does not expire. So when I look at edit view for products, which I'm not caching, I can see the change saved (just added a word to the title), but when I view show, it still has the old info.
If your using the aspen/bamboo stack I dont think caching works in rails as the apps are fronted by varnish which does caching for you
I don't know about "caches_action", but you can try to expire manually all cache and see what happens.
def update
# expire_action :action => :show
Rails.cache.clear
end
If is there any caching issue than this link will help you to find solution.
You can connect directly to dalli/memcached client through heroku console and then use flush_all to flush the cache.
Or refer this google-groups link

Render a page as a saved HTML file using Rails 3.0?

I'm building a simple website generator application in Rails 3.0. I'd like a "publish" action in a controller that works just like an ordinary "show" action, but instead, saves a page as an HTML file in the "public" directory instead of displaying it in the browser. That is, I'd like to use the Rails render mechanism to create a file instead of providing an HTTP response.
What's the best way to do this?
Should I simply add caches_page :publish to the controller?
Or use render_to_string and File.new?
You can use render_to_string method: http://apidock.com/rails/AbstractController/Rendering/render_to_string
You still need to respond from the controller though. Maybe redirect to the page you just saved?
I would go with page caching.
Then if you have editable content, the pages should be automatically generated. You could then write a system task which bundles them up as a web site.
see (whatever)/actionpack/lib/action_controller/caching/pages.rb for instructions.
I found that page caching using caches_page won't work for me because there is no way to show a notification or redirect to another page after caching the page. The method render_to_string (suggested by #Grocery) is the way to go. Here's the example controller code:
def publish
#article = Article.find(params[:id])
html = render_to_string(:template => "articles/template.html.haml", :layout => 'article' )
FileUtils.makedirs("#{Rails.root}/public/articles/") unless File.exists?("#{Rails.root}/public/articles/")
File.open("#{Rails.root}/public/articles/#{#article.filename}.html", 'w') {|f| f.write(html) }
respond_to do |format|
format.html # publish.html.erb
end
end

RJS with Devise gem

What would be the proper way to set Devise gem (ruby on rails v3) in RJS style (example: http://railscasts.com/episodes/43-ajax-with-rjs)?
I usually create a create.js.erb file with alert(#error). When using devise I don't know how to properly get #error value. I would like to display all messages as javascript alerts.
I think, to achieve this you will need to write your own controllers (inherited from devise) and views. And then add respond_to :html, :js to this controllers. After this, controllers will be able to respond to javascript requests and you can manage your alerts.Read doc for how to create custom Devise views here: Devise

Rails app doesn't see my views

I've on a while on rails now and here's the problem I've been having on and on:
When I create a controller through:
"rails generate controller ControllerName ViewName"
I get everything working as I want but if for some reason I create the controller through:
"rails generate controller ControllerName"
and then just add ViewName.html.erb to the folder inside views that has the same name as my controller things would go wrong.
So the concrete case is me writing:
rails generate controller Subjects list show.
Which creates for me:
1.controllers>subjects_controller.rb
2.views>subjects>list.html.erb
3.views>subjects>show.html.erb
So this whole thing works fine.But as I already said if I need another view; let's say "new" I just add "new.html.erb" next to the other *.html.erb files and an action:
def new
end
to my subjects_controller.rb then it won't work.
The two previous views would keep working but any other "*html.erb" created outside the command line wouldn't.
Is there anywhere else where info about views is being stored?.
I'm a Windows 7 user (32 bit).Rails version=3.0.3. WebServer=WEBrick.
Text editor = E-TextEditor
This is most likely caused by your routes not being correctly configured. So it would be helpful to see the content of your routes.rb
In your case I think the best way to configure the routes is to use the resources mapping:
resources :subjects
This will by default create routing for the standard RESTful actions :index, :show, :edit, :update, :new, :create and :destroy.
For more detailed information about the routing, I would recommend Rails Routing from the Outside In