Rails Cache Action Won't Expire - ruby-on-rails-3

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

Related

Rails 3 + Devise 2 + JsonP / Callbacks

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;)

how to post :create from the default update url, rails 3

I'm sure this is pretty basic, but I'm somewhat new to rails and struggling to find a solution via search.
I'm implementing a message model to enable private messaging on a forum. I have the models resource nested within a users resource.
Currently the model works, but I want to enable a user to reply to a private message directly on the message show page. I.e users/1/messages/16 instead of users/1/messages/new. Currently this is the default route for 'update' within the MessagesController. Is there anyway to make the form on this page hit the 'create' action within the controller, instead of the 'update'?
Thanks.
Sure, I would try something like this:
On your show page just add a new form.
<%= form_for :message, :url => new_user_message_path do |f| %>
...
<% end %>
You can check the routes of your application using this command:
bundle exec rake routes
I suggest you to read the rails guide: http://guides.rubyonrails.org/

rspec render_views ignores layouts? want to test static cached page does not display flash message

I'm trying to test that "static" pages (they're ERB, but get cached), generated through rails, don't render any stray flash notices left over by the authentication system (Devise) or wherever else.
I've tried writing this controller spec, but it appears that response.body only renders the template, not its layouts?
describe "so that static caching can be used" do
render_views
specify "flash notices are not rendered" do
# edit: the following flash lines don't do anything
# it's not the right flash object, this one is intended for
# inspecting after request not setting before request
flash[:notice] = "flash boo"
flash[:error] = "flash boo"
flash[:alert] = "flash boo"
get :show, :page => 'privacy_policy'
response.body.should have_content('flash boo')
end
end
class StaticPagesController < ApplicationController
layout 'master'
def show
response.headers['Cache-Control'] = "public, max-age=#{6.hours}"
render "static_pages/#{params[:page]}"
end
end
I've tried changing to a layout which does render flash notices, and even inserting the text into the layout template, but can't make the spec fail.
Is there a way to ask rspec to render the template with the appropriate layouts as well?
Is a controller spec the wrong way to try and do this?
It seems out of place, as it's more to do with which layouts are being used, and their contents, but the rendering process starts at the controller, it receives the result, and I can manipulate the flash hash contents before rendering.
Versions:
rails (3.0.10),
rspec-rails (2.6.1),
rspec-core (2.6.4)
Thanks, Nick
Turns out this isn't the right approach. It should be an integration test (cucumber, request spec, etc) as it's testing several layers. That and rails doesn't seem to render the templates inside their layouts at this level.
So in integration test:
Set up a flash message by making a request to a controller which does nothing else (create a dummy controller & routing in your test code), then hit the page of concern and make sure the flash notice isn't rendered.
e.g. https://gist.github.com/1178383
It seems like a long way round but it will cover it.

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

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