Error using private or protected methods in subclasses of ApplicationController - ruby-on-rails

I have a filter shared between some controllers, which is primarily declared as private in ApplicationController. This method sets find and pagination conditions for controllers.
class ApplicationController < ActionController::Base
...
protected # or private
# Define parametros de busca
def set_find_opts(klass)
#filter = params[:f].to_i || nil
#order = klass.set_order params[:o]
#opts = { :page => params[:page] }
#opts[:order] = #order if #order
end
...
end
class Admin::UsersController < AdminController
...
before_filter(:only => :index) {|c| c.set_find_opts User }
...
end
I'm getting this error:
1) Error:
test_should_get_index(Admin::UsersControllerTest):
NoMethodError: protected method `set_find_opts' called for #<Admin::UsersControl
ler:0x848f3ac>
app/controllers/admin/users_controller.rb:4
functional/admin/users_controller_test.rb:9:in `test_should_get_index'
Why it happens?

You can't send private/protected messages with an explicit receiver (object.protected_method) like you are doing in your block. You can try c.send(:set_find_opts, User) or c.instance_eval { set_find_opts(User) }.

Related

How to break down decent-exposure code to classic Rails way?

Can anyone break this code down for me and explain how this can be done in classic Rails way with callbacks(if any) and methods?
class SearchController < ApplicationController
expose :search_result, -> { SearchService.new(search_params).call }
def search_params
params.permit(:q, :scope)
end
end
class SearchController < ApplicationController
def index
#search_result = SearchService.new(search_params).call
end
def search_params
params.permit(:q, :scope)
end
end
expose :search_result, -> { SearchService.new(search_params).call } creates a variable #search_result

Rails class method not defined

I have a controller which calls a class method from a model. However, I got undefined method 'where' for Jira:Class.
controller:
module Api
module V1
class JiraController < ApplicationController
def index
jira = Jira.where()
jira_stat = JiraStat.new(jira)
render json: [
{
t('jira.api.status') => jira_stat.status,
t('jira.api.number_of_jiras') => jira_stat.jira_total
}
]
end
end
end
end
model:
# frozen_string_literal: true
require 'active_model'
class Jira
include ActiveModel::Model
include JiraKit
attr_accessor :status, :jira
def self.where(status_name = 'all')
if status_name == 'all'
jiras = JiraKit.where.jira_issues(status: ['open', 'submitted', 'in
progress', 'in review', 'closed'])
elsif
jiras = JiraKit.where.jira_issues(status: [status_name])
end
new(#status = status_name, #jira = jiras)
end
end
I think I have used self keyword. But I don't know why I can't access that method. If I create an instance of Jira model, I am able to access that method.

How to pass :current_user in Graphql resolver

I have QueryType
Types::QueryType = GraphQL::ObjectType.define do
name 'Query'
field :allProjects, function: Resolvers::Projects
end
And Resolver like this
require 'search_object/plugin/graphql'
module Resolvers
class Projects
include SearchObject.module(:graphql)
type !types[Types::ProjectType]
scope { Project.all }
ProjectFilter = GraphQL::InputObjectType.define do
name 'ProjectFilter'
argument :OR, -> { types[ProjectFilter] }
argument :description_contains, types.String
argument :title_contains, types.String
end
option :filter, type: ProjectFilter, with: :apply_filter
option :first, type: types.Int, with: :apply_first
option :skip, type: types.Int, with: :apply_skip
def apply_first(scope, value)
scope.limit(value)
end
def apply_skip(scope, value)
scope.offset(value)
end
def apply_filter(scope, value)
branches = normalize_filters(value).reduce { |a, b| a.or(b) }
scope.merge branches
end
def normalize_filters(value, branches = [])
scope = Project.all
scope = scope.where('description ILIKE ?', "%#{value['description_contains']}%") if value['description_contains']
scope = scope.where('title ILIKE ?', "%#{value['title_contains']}%") if value['title_contains']
branches << scope
value['OR'].reduce(branches) { |s, v| normalize_filters(v, s) } if value['OR'].present?
branches
end
end
end
I want to access current_user in the resolver so i can access current_user.projects not Project.all. I am very new to graphql and learning.
Everything works but i just need to understand the whole flow on how i can get old of the ctx in the resolver.
First you need to set the current_user in the context. This happens in your GraphqlController.
class GraphqlController < ApplicationController
before_action :authenticate_user!
def execute
variables = ensure_hash(params[:variables])
query = params[:query]
operation_name = params[:operationName]
context = {
current_user: current_user,
}
result = HabitTrackerSchema.execute(query, variables: variables, context: context, operation_name: operation_name)
render json: result
rescue => e
raise e unless Rails.env.development?
handle_error_in_development e
end
# ...
end
Once it's done, you can access the current_user from a query (or a mutation) simply by writing:
context[:current_user]
To make things even simpler, you can add a current_user method toTypes::BaseObject (app/graphql/types/base_object.rb) and you'll be able to call current_user from the #resolve methods.
module Types
class BaseObject < GraphQL::Schema::Object
field_class Types::BaseField
def current_user
context[:current_user]
end
end
end

ruby instace variable scope in homecontroller

i have class HomeController
class HomeController < ApplicationController
def event_one
Req = **endpoint.connection**
res = req.body**(json format)**
#events = res
end
def event_two
#events
end
end
Can i use one instance variable(#events) which got response from endpoint in event_one method,from another event_two method.
try using this DRY code:
class HomeController < ApplicationController
before_action :set_events, only: [:event_one, :event_two]
def event_one
#your code here
# for example puts #events
end
def event_two
#your code here
# for example puts #events
end
private
def set_events
req = **endpoint.connection**
res = req.body**(json format)**
#events = res
end
end
you can achieve use a private method to set evnets
class HomeController < ApplicationController
def event_one
set_events
end
def event_two
set_events
end
private
def set_events
Req = **endpoint.connection**
res = req.body**(json format)**
#events = res
end
end
You can also call this method using filter of you want to set for every action of this controller.
Hope this will help!

confused, where are the defintions of show and index actions?

I'm looking at this code, I can see that is says actions: show and index but where are the methods show and index??
http://github.com/railsdog/spree/blob/master/core/app/controllers/products_controller.rb
class ProductsController < Spree::BaseController
HTTP_REFERER_REGEXP = /^https?:\/\/[^\/]+\/t\/([a-z0-9\-\/]+\/)$/
#prepend_before_filter :reject_unknown_object, :only => [:show]
before_filter :load_data, :only => :show
resource_controller
helper :taxons
actions :show, :index
private
def load_data
load_object
#variants = Variant.active.find_all_by_product_id(#product.id,
:include => [:option_values, :images])
#product_properties = ProductProperty.find_all_by_product_id(#product.id,
:include => [:property])
#selected_variant = #variants.detect { |v| v.available? }
referer = request.env['HTTP_REFERER']
if referer && referer.match(HTTP_REFERER_REGEXP)
#taxon = Taxon.find_by_permalink($1)
end
end
def collection
#searcher = Spree::Config.searcher_class.new(params)
#products = #searcher.retrieve_products
end
def accurate_title
#product ? #product.name : nil
end
end
My guess is that the actions method is loaded with resource_controller as a module from the lib directory. Then calling the actions method creates the index and show methods.
The class inherits from Spree::BaseController and ActionController. Spree::BaseController has method action which takes method names as messages.

Resources