Call same controller method with different params ruby - ruby-on-rails

I have a Private and a Third party inspection. After creating private inspection record automatically I need to create a third party Inspection. So that I have to call the create_history method from controller again with different params
class HomesController < BaseController
def create_history
#<ActionController::Parameters {"request_type"=>"Private", "user_id"=>"25" "requested_at"=>"Oct 28, 2022","private_inspection_type_id"=>"23780"} permitted: true>
inspection_request = #home.inspection_requests.new(inspection_request_history_params)
inspection_request.save
if inspection_request.get_paired_inspection.present?
inspection_request_history_params = {request_type: "Third Party", third_party_inspection_id: inspection_request.get_paired_inspection.id, status: inspection_request.status, user_id: inspection_request.user_id, requested_at: inspection_request.requested_at }
create_history
end
end
def inspection_request_history_params
params.require(:inspection_request).permit(:request_type, :user_id, :requested_at, :performed_at, :private_inspection_type_id, :third_party_inspection_id)
end
When i tried calling create_history method by passing different params like this I'm not getting the params . Any help is appreciatable

I think it's better if you put inspection_request.save on different method
class HomesController < BaseController
def create_history
inspection_request = create_inspection_requests(inspection_request_history_params)
if inspection_request.get_paired_inspection.present?
create_inspection_requests({
request_type: "Third Party",
third_party_inspection_id: inspection_request.get_paired_inspection.id,
status: inspection_request.status,
user_id: inspection_request.user_id,
requested_at: inspection_request.requested_at
})
end
end
private
def create_inspection_requests(attributes)
inspection_request = #home.inspection_requests.new(attributes)
inspection_request.save
return inspection_request
end
def inspection_request_history_params
params.require(:inspection_request).permit(:request_type, :user_id, :requested_at, :performed_at, :private_inspection_type_id, :third_party_inspection_id)
end
end

Related

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.

Rendering json data fields from mysql db in rails response object

I have a rails 4.2 app that uses mysql db 5.7 which supports json fields. So my user model has a field called display_pic which is a json object.
class User < ActiveRecord::Base
serialize :display_pic, JSON
....
In the action get_user I render user as follows
def get_user
#u = User.where(...)
render json: { user: #u }
end
The problem is that the json field display_pic doesn't come out as a nested json object, rather it is rendered as a string. I would like to have a response like the following
{
"user": {
"name": "some name",
"email": "some email",
"display_pic": {
"url": "http://someurl.com",
"width": "400px",
}
}
}
Probably a better way to do this, but you can format it as json in the serializer.
class UserSerializer < ActiveModel::Serializer
attribute :name
attribute :email
attribute :display_pic
def display_pic
JSON.parse(object.display_pic)
end
end
Use the following code it will solve your problem:
def get_user
#u = User.where(...)
render json: { user: JSON.parse(#u)}
end
Have you tried to use the method .as_json ?
def get_user
#u = User.where(...)
render json: #u.as_json
end
You should have not need to set serialize :display_pic, :JSON, but you can overload the method in your user.rb class in order to get on response references or methods results authomatically loaded on your front end:
class PlayerCharacter < ApplicationRecord
[...]
def as_json(options = {})
super(options.merge(include: [ :reference1, :reference2]).merge(methods: [:method_name1, :method_name2])
end
end
EDIT:
you could add display_pic as follow:
class PlayerCharacter < ApplicationRecord
[...]
def as_json(options = {})
super(options.merge(include: [ :display_pic])
end
end

HGET in private method not returning hash

Some reason my hget is not finding or returning a hash I set in a public method. I can't figure out why.
This is all in one controller that inherits from ApplicationController, which is where I define my redis initializer:
def redis
Thread.current[:redis] ||= Redis.new
end
Then in my controller I do this to set the hash:
def return_customer
email = params["email"]
customer = Customer.find_by(email: email)
credit_amount = customer.credit_amount.to_f
customer_data = {email: email, customer_id: customer.id, credit_amount: credit_amount}
redis.hset("shop:#{customer.shop.id}:customer", customer_data, customer_data.inspect)
render json: customer
end
Then finally I have this private method I use in other methods in the same controller, this is the part that's not working:
private
def get_customer_from_redis
shop = Shop.find_by(shopify_domain: params["shop"])
customer_info = redis.hget("shop:#{shop.id}:customer", customer_data)
eval(customer_info)
end
This is the error that's returned
TypeError (no implicit conversion of nil into String):
I'd recommend you rather than using .inspect use .to_json like this:
def return_customer
email = params["email"]
customer = Customer.find_by(email: email)
credit_amount = customer.credit_amount.to_f
customer_data = {email: email, customer_id: customer.id, credit_amount: credit_amount}
redis.set("shop:#{customer.shop.id}:customer", customer_data.to_json)
render json: customer
end
And then in your private method
def get_customer_from_redis
shop = Shop.find_by(shopify_domain: params["shop"])
customer_info = redis.get("shop:#{shop.id}:customer", customer_data)
JSON.parse(customer_info) if customer_info
end

Bad formatted json

There is a model Event in my app and I have two problems, the first is the returned json that comes messed with the request:
$ curl http://0.0.0.0:3000/events
it gives me
{
"events":[
{"events":{"name":"First"}},
{"events":{"name":"Second"}}],
"meta":{"total_pages":9,
"next_page":"http://0.0.0.0:3000/events?page=2"}
}
which I think it should gives
{
"events":[
{"name":"First" },
{"name":"Second"}
],
"meta":{
"total_pages":9,
"next_page":"http://0.0.0.0:3000/events?page=2"
}
}
also I am using the gems draper and active_model_serializer, and the second problem is that the json format doesn't respect the Serializer definition:
class EventSerializer < ActiveModel::Serializer
attributes :id, :date_end
end
I would like to know where should I look to fix these problems.
Answering the questions, the code that generate the json:
class EventsController < ApplicationController
def index
#events = Event.order(:name).page(params[:page])
#events = #events.where(id: params[:ids].split(',')) if params[:ids].present?
render json: #events.decorate, meta: { total_pages: #events.total_pages, next_page: next_page_url(#events)}
end
def next_page_url(event)
unless event.last_page?
next_page = event.current_page + 1 unless event.last_page?
events_url(params.merge({:page => next_page}))
end
end
and the decorator:
class EventDecorator < Draper::Decorator
delegate :current_page, :total_pages, :limit_value
def name
object.name
end
end

Call a Method Model inside Controller

I have the following model;
(app/models/student_inactivation_log.rb)
class StudentInactivationLog < ActiveRecord::Base
belongs_to :student
belongs_to :institution_user
belongs_to :period
validates_presence_of :student_id, :inactivated_on, :inactivation_reason
INACTIVATION_REASONS = [{ id: 1, short_name: "HTY", name: "You didn't study enough!"},
{ id: 2, short_name: "KS", name: "Graduated!"},
{ id: 3, short_name: "SBK",name: "Other Reason"}]
Class methods
class << self
def inactivation_reason_ids
INACTIVATION_REASONS.collect{|v| v[:id]}
end
def inactivation_reason_names
INACTIVATION_REASONS.collect{|v| v[:name]}
end
def inactivation_reason_name(id)
INACTIVATION_REASONS.select{|t| t[:id] == id}.first[:name]
end
def inactivation_reason_short_name(id)
INACTIVATION_REASONS.select{|t| t[:id] == id}.first[:short_name]
end
def inactivation_reason_id(name)
INACTIVATION_REASONS.select{|t| t[:name] == name}.first[:id]
end
end
# Instance methods
def inactivation_reason_name
self.class.inactivation_reason_name(self.inactivation_reason)
end
def inactivation_reason_short_name
self.class.inactivation_reason_short_name(self.inactivation_reason)
end
def inactivation_reason_id
self.class.inactivation_reason_id(self.inactivation_reason)
end
end
I would like to call these inactivation reasons from my controller, which is app/controllers/student/session_controllers.rb file:
class Student::SessionsController < ApplicationController
layout 'session'
def create
student = Student.authenticate(params[:student_number], params[:password])
if student.active
session[:student_id] = student.id
redirect_to student_main_path, :notice => 'Welcome!'
elsif (student and student.student_status == 3) or (student and !student.active)
flash.now.alert = "You can't login because #REASON_I_AM_TRYING_TO_CALL"
render 'new'
else
....
end
end
I would like to show students their inactivation reason on the systems if they can't login.
How can I call my INACTIVATION_REASONS from this controller file? Is it possible?
Thanks in advance!
That's just a constant, so you can call it as constant anywhere.
StudentInactivationLog::INACTIVATION_REASONS
Update
I realized actually what you want is to use a reason code or short name saved in db to represent the string.
If so, I recommend you to use the short name directly as Hash. "id" looks redundant for this light case.
INACTIVATION_REASONS = {"HTY"=>"You didn't study enough!",
"KS"=>"Graduated!",
"SBK"=>"Other Reason"}
validates :inactivation_reason, inclusion: { in: INACTIVATION_REASONS.keys,
message: "%{value} is not a valid short name" }
def full_reason_message
INACTIVATION_REASONS[self.inactivation_reason]
end
Then, to show full message of a reason in controller
reason = #student.full_reason_message
This is the idea. I havn't checked your other model codes. You'll need to save reason as the short name instead of id, and need to revise/remove some code if you decide to use it in this way.

Resources