How to cache index page with pagination? - ruby

Suppose this my one of admin model
ActiveAdmin.register Theme do
menu :if => proc{ current_admin_user.super_admin?}
after_filter :only => [:create, :update, :destroy] do
expire_action :action => :show
expire_action :action => :index
end
controller do
caches_action :index, :show
end
end
with this code caching is done, but on index page with pagination i am facing issue, that is i am not able to visit another page of Theme.
How to implement something like this
https://github.com/amatsuda/kaminari#creating-friendly-urls-and-caching

this is what fixed the issue:
caches_action :index, :cache_path => Proc.new { |c| c.params }
This will generate new cache for specific paginate param's
Read More

Related

No Route Matches DELETE Sessions Api

I've started to create an Api for my rails application. I am currently creating the Sessions Controller for Log in.
But for some reason I am getting this error
Started DELETE "/api/v1/sessions/?auth_token=6157d3673725013ebddbb5e26e8cd64756949110"
for 127.0.0.1 at 2014-08-29 18:54:18 -0700
ActionController::RoutingError (No route matches [DELETE] "/api/v1/sessions"):
I am not understanding why this is happening. Sign Out seems to work perfectly on the actual web application.
I know it may need an ID according to the rake routes but I'm not sure how to implement this.
API CONTROLLER
module Api
module V1
class SessionsController < ApplicationController
skip_before_filter :verify_authenticity_token,
:if => Proc.new { |c| c.request.format == 'application/json' }
respond_to :json
def destroy
sign_out
render :status => 200,
:json => { :success => true,
:info => "Logged Out",
:data => {} }
end
end
end
end
CONTROLLER
class SessionsController < ApplicationController
def destroy
sign_out
redirect_to root_path
end
end
SESSION HELPER
def sign_out
current_user = nil
cookies.delete(:remember_token)
end
ROUTES
### API Routes
namespace :api, defaults: {format: 'json'} do
scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do
resources :sessions, only: [:new, :create, :destroy]
end
end
RAKE ROUTES
api_v1_sessions POST /api/v1/sessions(.:format)
api/v1/sessions#create {:format=>"json"}
api_v1_session DELETE /api/v1/sessions/:id(.:format)
api/v1/sessions#destroy {:format=>"json"}
From the documentation
You can use resource instead of the resources routes helper. It's used to create routes for a singular resource that you don't access using IDs.
namespace :api, defaults: {format: 'json'} do
namespace :v1, constraints: ApiConstraints.new(version: 1, default: true) do
resource :session, only: [:new, :create, :destroy]
end
end
which will give you
GET /session/new
POST /session
DELETE /session

Totally change url for action

I have the following in my routes:
resource :login, only: [:new, :create, :destroy]
resources :users, only: [:new, :create] do
resources :notes
end
but I would like to have url 'my-domain/login' instead of 'my-domain/login/new' and 'my-domain/register' instead of 'my-domain/users/new'.
How can I do than? I have tried the following but it didn't work:
match 'login' => 'login#new'
match 'register' => 'users#new'
resource :login, only: [:create, :destroy]
resources :users, only: [:create] do
resources :notes
end
This gives me error
undefined local variable or method `logins_path' for #<#<Class:0x007fd99c40c608>:0x007fd99c87bdd8>
while visiting 'my-domain/login'
Try this:
match '/login', to: 'login#new'
match '/register', to: 'users#new'
resource :login, only: [:new, :create, :destroy]
A very good tutorial (dare I say "The Best") for learning Ruby on Rails is railstutorial.org. There is a chapter about making a working login and register page.
UPDATE
If you don't want users to visit /users/new I think your current users resources works:
resources :users, only: [:create] do
resources :note
end
Since it only matches a route for users/create. You can also redirect users to /register if they go to /users/new. The new action in your Users Controller:
def new
redirect_to register_path
end

Devise & CanCan — Issues with CanCan 2.0 API

I'd like to have additional attributes for my User model and don't want to create a separate Profile model.
I'm trying to update custom fields with standart «update» from RESTful set of actions:
class UsersController < ApplicationController
before_filter :authenticate_user!
# ...
def update
#user = User.find(params[:id])
authorize! :update, #user
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
end
And it all goes fine except the fact that the current_user is able to update any user's profile. It seems I can't restrict any User action. I've tried:
can :update, User, :id => user.id
and
cannot :update, User # at all
with no luck. Using Devise 1.5.0 and CanCan 2.0.0.alpha
Here's my ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new(:role => nil) # guest user (not logged in)
can :access, :all
if user.admin?
can :manage, :all
else
can :read, Review
if user.customer?
can :update, User, :id => user.id
can [:create, :update, :destroy], Review, :user_id => user.id
end
end
end
end
Code looks good to me.
What if you try to simplify the second condition first and take out the customer condition? And maybe take out "can :access, :all
Something like:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new(:role => nil) # guest user (not logged in)
if user.admin?
can :access, :all
else
can :read, :all
can :update, :users, :id => user.id
can [:create, :update, :destroy], :reviews, :user_id => user.id
end
end
end
Does your restriction work for Reviews (that user can only edit his own reviews) ?
I have a similar ability file but I always work with a seperate profile model..

Fail at redirect expectation in a controller spec

I am using Devise 1.4.2, RSpec 2.6.0 and Rails 3.1.0.rc6. My routes.rb looks like this:
scope "(:locale)", :locale => /e(s|n)/ do
resources :demotivideos, :only => [:index, :show]
devise_for :users
namespace "admin" do
resources :demotivideos, :except => [:index, :show]
end
end
I am spec'ing that, when a not logged in user acces new, create or update, he should be redirected to new_user_session_path. For this, I am using the following code
context "when not logged in" do
before(:each) do
sign_out user
end
describe "GET new" do
it "should redirect to new user session" do
get :new
response.should redirect_to(new_user_session_path)
end
end
describe "POST create" do
it "should redirect to new user session" do
post :create, :demotivideo => valid_attributes
response.should redirect_to(new_user_session_path)
end
end
describe "PUT update" do
it "should redirect to new user session" do
put :update, :id => 1, :demotivideo => valid_attributes
response.should redirect_to(new_user_session_path)
end
end
end
All are failing because of the same reason: expected route includes the locale (by default en) but the actual redirect was to the same path without locale. My application controller was modified as told in Rails Guides:
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :set_locale
def default_url_options(options={})
logger.debug "default_url_options is passed options: #{options.inspect}\n"
{ :locale => I18n.locale }
end
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
end
What am I doing wrong?
Seems like though Rails Guides uses def default_url_options in Devise you need def self.default_url_options. Don't know the difference, though.

Rails 3 - Restricting formats for action in resource routes

I have a resource defined in my routes.
resources :categories
And I have the following in my Category controller:
def show
#category = Category.find(params[:id])
respond_to do |format|
format.json { render :json => #category }
format.xml { render :xml => #category }
end
end
The controller action works fine for json and xml. However I do NOT want the controller to respond to html format requests. How can I only allow json and xml? This should only happen in the show action.
What is the best way to achieve this?
Also is there any good tips for DRYing up the respond_to block?
Thanks for your help.
I found that this seemed to work (thanks to #Pan for pointing me in the right direction):
resources :categories, :except => [:show]
resources :categories, :only => [:show], :defaults => { :format => 'json' }
The above seems to force the router into serving a format-less request, to the show action, as json by default.
You must wrap those routes in a scope if you want to restrict them to a specific format (e.g. html or json). Constraints unfortunately don't work as expected in this case.
This is an example of such a block...
scope :format => true, :constraints => { :format => 'json' } do
get '/bar' => "bar#index_with_json"
end
More information can be found here: https://github.com/rails/rails/issues/5548
This answer is copied from my previous answer here..
Rails Routes - Limiting the available formats for a resource
You could do the following in your routes.rb file to make sure that only the show action is constrained to json or xml:
resources :categories, :except => [:show]
resources :categories, :only => [:show], :constraints => {:format => /(json|xml)/}
If this doesn't work you could try explicitly matching the action:
resources :categories, :except => [:show]
match 'categories/:id.:format' => 'categories#show', :constraints => {:format => /(json|xml)/}
constraints was not working for POST requests and then I tried defaults it works for all.
namespace :api, :defaults => { :format => 'json' } do
namespace :v1 do
resources :users do
collection do
get 'profile'
end
end
post 'signup' => 'users#create'
post 'login' => 'user_sessions#create'
end
end
I was using Rails 4.2.7

Resources