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

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

Related

Issue with HomeController showing undefined method

I am trying to pass stored_products from shopify into a Rails app but keep getting a home controller error at https://f588240c.ngrok.io/ i have made updates, with no luck and restarted the server a number of times with no luck.
Any help would be welcomed. Heres the code
class Api::V1::HomeController < ShopifyApp::AuthenticatedController
def index
#products = ShopifyAPI::Product.find(:all, params: { limit: 10 })
#products.each do |product|
StoredProduct.where(shopify_id: product.id)
.first_or_create do |stored_product|
stored_product.shopify_id = product.id
stored_product.shopify_title = product.title
stored_product.shopify_handle = product.handle
stored_product.shopify_image_url = product.image.src
stored_product.shop_id = #shop.id
stored_product.save
product.images.each do |image|
ProductImage.where(shopify_id: image.id)
.first_or_create do |product_image|
product_image.image_url = image.src
product_image.stored_product_id = stored_product_id
product_image.shopify_id = image.id
end
end
end
end
#stored_products = StoredProduct.belongs_to_shop(#shop.id)
end
end
From the authenticated controller
private
def set_shop
#shop = Shop.find_by(id: session[:shopify])
set_locale
end
from the store_products.rb file
class StoredProduct < ApplicationRecord
belongs_to :shop
has_many :product_images
scope :belongs_to_shop, -> shop_id { where(shop_id: shop_id) }
end
For this specific issue/code tutorial, the private set_shop method should be set like follows:
def set_shop
#shop = Shop.find_by(id: session[:shop_id])
set_locale
end
The other answer has params instead of session
The problem is that #shop is nil. The error message says it cannot call the method .id on NilClass.
In the image I can see that you have a shop_id in the params so you might just need to change your code here:
def set_shop
#shop = Shop.find_by(id: params[:shop_id])
set_locale
end
But that depends on your code, so please double check.

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.

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!

Add scope in concerns for various models

In apps/models/concerns/deactivable.rb
module Deactivatable
extend ActiveSupport::Concern
included do
scope :alive, -> { where(:deactivated_at => nil) }
end
def deactivate(t = Time.current)
update_attribute(:deactivated_at,t)
end
def activate
update_attribute(:deactivated_at,nil)
end
def deactivated?
deactivated_at.present?
end
end
This is being included in 2 models, app/models/activity_rules/activity_detection_rule.rb and app/models/concerns/generic_campaign.rb.
There are 2 more models which contain the same methods with different attribute name.
In redeemable.rb,
class Redeemable < ActiveRecord::Base
scope :alive, -> { where("(deactivation_date is null) and (expiry_date is null or expiry_date >= ?)",Date.today) }
def deactivate(t = Time.current)
update_attribute(:deactivation_date,t)
end
def reactivate
update_attribute(:deactivation_date,nil)
end
def deactivated?
deactivation_date.present?
end
end
and in surprise_set.rb
scope :alive, -> { where("deactivation_date is null") }
with the same 3 methods as redeemable.rb.
How to use Deactivable concern to DRY up the other two models?
You could return the attribute that indicates the time of deactivation from a class method. You can provide a default implementation in your concern and override in the class that includes the concern if you need to:
module Deactivatable
extend ActiveSupport::Concern
included do
scope :alive, -> { where(deactive_attr => nil) }
def self.deactive_attr
:deactivated_at
end
end
def deactivate(t = Time.current)
update_attribute(self.class.deactive_attr, t)
end
def activate
update_attribute(self.class.deactive_attr, nil)
end
def deactivated?
self.send(self.class.deactive_attr).present?
end
end
Then, in classes where you want to provide a different attribute you can add a class method:
include Deactivatable
def self.deactive_attr
:deactivation_date
end
You could also DRY up your alive scope a bit by allowing the class that includes the concern to define the conditions for 'aliveness'. In the concern you can define the default
scope :alive, -> { where(self.active_conditions) }
def self.active_conditions
{ self.deactive_attr => nil }
end
You can then provide a different implementation of active_conditions in the class itself:
self self.active_conditions
["(deactivation_date is null) and
(expiry_date is null or expiry_date >= ?)", Date.today]
end

Error using private or protected methods in subclasses of ApplicationController

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) }.

Resources