cache sweeper not working for custom method Rails 4 - ruby-on-rails

I am using fragment caching in my rails 4 project. I have cities controller and city_sweeper
cities_controller.rb
cache_sweeper :city_sweeper, :only => [:update, :destroy]
.
.
def update_featured
#city = City.unscoped.find(params[:id])
if params[:featured]
#city.update_attribute(:featured, params[:featured])
end
render :text => "success:
end
.
end
and in my city_sweeper.rb I have this code
class CitySweeper < ActionController::Caching::Sweeper
observe City
def after_update(city)
expire_cache(city)
end
def after_destroy(city)
expire_cache(city)
end
def after_update_featured(city)
expire_cache(city)
end
def expire_cache(city)
expire_fragment "city_index_#{city.id}"
end
end
its working fine with CRUD operation, but its not working for my custom method.its calling my sweeper.rb , but I am not getting city object there. I am getting this error:
NoMethodError (undefined method `expire_fragment' for #<CitySweeper:0xab9f1e0 #controller=nil>):

You can expire the fragment cache using this
UPDATE
if #cities.present?
#cities.each do |city|
cache(action: 'recent_update',key: "city_index_#{city.id}", skip_digest: true) do
...
end
end
end
In Sweeper
class CitySweeper < ActionController::Caching::Sweeper
observe City
.....
def expire_cache(city)
expire_fragment(controller: 'cities', action: 'recent_update',key: "city_index_#{city.id}")
end
end

Related

Rails action being called twice

As the title says, my action is being fired twice when clicked a single time.
The action is just meant for copying a model then saving the copied model.
module RailsAdmin
module Config
module Actions
class CopyAction < RailsAdmin::Config::Actions::Base
RailsAdmin::Config::Actions.register(self)
register_instance_option :member do
true
end
register_instance_option :http_methods do
[:get]
end
register_instance_option :controller do
proc do
if request.get? # EDIT
#newObject = #object.dup
objectNameCopy = #object.name + "_copy_"
#queues = Filter.where('name LIKE ?',"%#{objectNameCopy}%")
x = 1
#queues.each do |q|
x=x+1
end
#newObject.name = #newObject.name + "_copy_" + x.to_s
#newObject.key = #newObject.key + "_copy_" + x.to_s
if #newObject.save!
respond_to do |format|
format.html { redirect_to_on_success }
end
else
#newObject.errors.full_messages.each do |message|
flash.now[:error] = message
end
end
end
end
end
register_instance_option :link_icon do
'fa fa-copy'
end
end
end
end
end
I have noticed that by entering the URL manually, it works as intended.
When clicking the icon to run this action, it opens a URL with a # at the end. I've not a clue where this could be coming from.
As a #max said in the comments its probably a turbolinks issue, try disabling it for your action like this
module RailsAdmin
module Config
module Actions
class CopyAction < RailsAdmin::Config::Actions::Base
RailsAdmin::Config::Actions.register(self)
# ADD THIS
register_instance_option :pjax? do
false
end
end
end
end
end

Rails controller isn't getting specific params

I'm trying to follow wicked tutorial for creating an object partially
( https://github.com/zombocom/wicked/wiki/Building-Partial-Objects-Step-by-Step )
The problem is, I am having trouble creating the object itself. I've tried with and without strong params, or even making the call out of the controller, but can get it passed. What am I doing wrong?
class ProspectsController < ApplicationController
include Wicked::Wizard
steps :signup, :business_details, :user_details
def show
create_prospect if params[:prospect_id].nil?
byebug # => prospect_id is no appearing => Not_found
#prospect = Prospect.find(params[:prospect_id])
render_wizard
end
def update
#prospect = Prospect.find(params[:prospect_id])
params[:prospect][:status] = 'users_detailed' if step == steps.last
#prospect.update_attributes(params[:prospect])
render_wizard #prospect
end
def create_prospect
#prospect = Prospect.create
new_prospect_build_path(prospect_id: #prospect.id)
end
# def prospect_params
# params.require(:prospect).
# permit(:user_first_name, :user_last_name, :user_email, :dni, :plan, :empresa_name, :empresa_email,
# :empresa_phone, :empresa_address, :empresa_web, :empresa_category, :empresa_summary, :user_birthday,
# :user_phone, :user_address, :sex, :iban_code, :status, :prospect_id)
# end
end
Routes:
resources :prospects, only: [:show, :update] do
resources :build, controller: 'prospects'
end
you're using same controller action for two routes:
GET /prospects/:prospect_id/build/:id => prospects#show
GET /prospects/:id => prospects#show
same with update.
If you will get to that controller by GET prospect_path you will not get :prospect_id, but :id.

Disable pagination for relationships

Given 2 resources:
jsonapi_resources :companies
jsonapi_resources :users
User has_many Companies
default_paginator = :paged
/companies request is paginated and that's what I want. But I also want to disable it for relationship request /users/4/companies. How to do this?
The best solution I found will be to override JSONAPI::RequestParser#parse_pagination like this:
class CustomNonePaginator < JSONAPI::Paginator
def initialize
end
def apply(relation, _order_options)
relation
end
def calculate_page_count(record_count)
record_count
end
end
class JSONAPI::RequestParser
def parse_pagination(page)
if disable_pagination?
#paginator = CustomNonePaginator.new
else
original_parse_pagination(page)
end
end
def disable_pagination?
# your logic here
# request params are available through #params or #context variables
# so you get your action, path or any context data
end
def original_parse_pagination(page)
paginator_name = #resource_klass._paginator
#paginator = JSONAPI::Paginator.paginator_for(paginator_name).new(page) unless paginator_name == :none
rescue JSONAPI::Exceptions::Error => e
#errors.concat(e.errors)
end
end

Displaying Associated Objects in Rails Views

I am working on a rails 4 application that currently has two models User and Status. In the user model I defined the association below. Both the status and user tables are populating with information. Statuses are loading with an associated user_id
User Model
class Status < ActiveRecord::Base
belongs_to :user
end
I have the following block in my show status view which will display the user_id and and the content of the status
<% #statuses.each do |status| %>
<div class="status">
<strong> <%=status.user_id%></strong>
<p> <%=status.content%></p>
I would like to display the user's first name instead. According the tutorial i'm taking I should be able to use this code since I have the association defined however it's returning the error below.
<%=#status.user.first_name%>
Error
#==>undefined method `first_name' for nil:NilClass
How can I display first_name in the controller? Do I need to define a new method for user or should the association provide?
Relevant Controller Code for Reference
class StatusesController < ApplicationController
before_action :set_status,:set_user, only: [:show, :edit, :update, :destroy]
# GET /statuses
# GET /statuses.json
def index
#statuses = Status.all
end
# GET /statuses/1
# GET /statuses/1.json
def show
puts "debug msg #{#status.inspect}"
end
# GET /statuses/new
def new
#status = Status.new
end
# GET /statuses/1/edit
def edit
end
# POST /statuses
# POST /statuses.json
...
...
...
private
# Use callbacks to share common setup or constraints between actions.
def set_status
#status = Status.find(params[:id])
puts "in set status"
end
def set_user
#status.user = User.find_by(#status.user_id)
end
# Never trust parameters from the scary internet, only allow the white list through.
def status_params
params.require(:status).permit(:content, :user_id)
end
end
Sees like there is no problem in your code. The error undefined method first_name for nil:NilClass means that the status object not associated with user or user have no field first_name. Try following code:
<% #statuses.each do |status| %>
<div class="status">
<strong> <%=status.user.try(:first_name) %></strong>
<p> <%=status.content%></p>
I am not sure what page you are trying to display <%=#status.user.first_name%> this on, but this should work.
You can use the will_paginate gem:
def show
#statuses = #statuses.paginate(page: params[:page])
end
add this to the view:
<%= will_paginate %>
or this should be the normal way:
def show
#statuses = #statuses.find(params[:id])
end

routing issue rails 3.1 thums_up and forem

I am trying to integrate forem with thumbs_up. I have inherited the forem Post model and controller.
Here is my controller :-
class PostsController < Forem::PostsController
def vote_up
begin
current_user.vote_for(#post = Post.find(params[:id]))
render :nothing => true, :status => 200
rescue ActiveRecord::RecordInvalid
render :nothing => true, :status => 404
end
end
end
Here is how the Post Controller of Forem looks like :-
module Forem
class PostsController < Forem::ApplicationController
before_filter :authenticate_forem_user
before_filter :find_topic
.
.
.
.
private
def find_topic
#topic = Forem::Topic.find(params[:topic_id])
end
end
end
Here is my routes:-
mount Forem::Engine, :at => "/forums"
resources :posts do
member do
post :vote_up
end
end
Here is my view :-
<%= link_to t('vote for this post!', :scope =>"forem.post"), main_app.vote_up_post_path(#post), :method => :post %>
This is the error which I am getting :-
ActiveRecord::RecordNotFound in PostsController#vote_up
Couldn't find Forem::Topic without an ID
What could be the issue?
Your problem is the before filter:
module Forem
class PostsController < Forem::ApplicationController
#...
before_filter :find_topic
#...
def find_topic
#topic = Forem::Topic.find(params[:topic_id])
end
and then:
class PostsController < Forem::PostsController
def vote_up
#...
So find_topic will be called before vote_up but the route for vote_up won't have a :topic_id; no :topic_id means that find_topic will be doing this:
#topic = Forem::Topic.find(nil)
and that's where your error comes from.
Three options come to mind:
Move vote_up to a separate controller class that doesn't inherit from Forem::ApplicationController.
Add a skip_filter :find_topic, :only => :vote_up to PostsController.
Adjust the route and link to get a :topic_id in the route.
If upvoting doesn't need the #topic then (1) or (2) would work, otherwise you'll have to go with (3).
check rake routesin command prompt,
and check id should be post :vote_up OR get:vote_up – ror_master
and use debugger in controller!
and write params there perhaps you will get solution.

Resources