Should I move my custom methods to model from controller?
Consider moving your logic into a service object. I think shoving controller logic into the model is simply moving the problem to a different location. Yes, you do isolate the logic to a single area, but there are instances where you end up moving logic to models because of convention rather than the fact that it really belongs there.
A service object can help you reduce duplication and isolate your business logic without getting the model too involved in things it does not need to know about (your repeated json response, for example).
class OrderService
def initialize(legacy_alphanumeric_product_number)
# do stuff
end
# do more stuff
end
From the controller, you can just call def check_whatever
@order = OrderService.new(params[:some_product_code])
@order.check_something
# do more stuff
end
Take a look at 7 Patterns to Refactor Fat ActiveRecord Models. I found it very helpful. There is also a RailsCasts episode on service objects (requires pro subscription). Calling model custom method in controller
Change the class method:
def self.add_manager(params)
To an instance method:def add_manager(params)
as @rally is an instance of your Rally class(answered in comments above - removing from unanswered list)
accessing custom method in model
Use local scope instand
public function scopeEmployee($query)
{
return $query->where('user_type', 'employee');
}
Your controller can be as it was ! public function index(){
$users = User::latest()->employee()->get();
return ProductsResource::collection($users);
}
How to write a custom function in a model?
Guess you are asking about the static functions:
class Order extends Model {
public static function myMethod() {
}
}
and you can call it anywhere like Order::myMethod();
Does it belong to controller or model?
A simple test (of whether it's a controller / model action) is to look at what the action is meant to do - does it work with data or params?
Rails models are meant to be "locked away" from much of the higher-level logic in your application; it's meant to provide a base-level set of actions to manipulate the data being inserted into your db; anything requiring request-level data should be handled in the controller.
As such...
redirect_to store_settings_store_path(id: current_store.id)
... because you're manipulating the flow of your app, your logic should stay in the controller.If you weren't redirecting (IE were only manipulating data), you'd be able to put this functionality into a before_create
callback in your model.
Moving method logic with SQL to model in rails project
You beat me to it (and went, essentially, with my second option). But, I'll post this anyway.
When you do this:
def array_of_disbursable_invoices
report = report.array_of_disbursable_invoices
render json: report
end
You're calling array_of_disbursable_invoices
on an instance. But, you don't instantiate Report
- thus, the undefined method 'array_of_disbursable_invoices' for nil:NilClass
error. So, I think you have two choices:
(1) You could call the method on an instance, something like:
report = Invoice.new.array_of_disbursable_invoices
(2) You could make the method a class method, something like:class Invoice < ActiveModel::Base
class << self
def array_of_disbursable_invoices
sql = "SELECT MIN(departure_date), ch_invoice.invoice_id
FROM ch_invoice
INNER JOIN ch_trip
ON ch_invoice.invoice_id = ch_trip.invoice_id
WHERE departure_date <= (SELECT SYS_EXTRACT_UTC(SYSTIMESTAMP)FROM DUAL)
AND service_rendered = 0
AND paid = 1
Group By ch_invoice.invoice_id"
connection.exec_query(sql)
end
end
end
I think I'd recommend (1). Also, personally, I'd use the ActiveRecord query interface instead of the SQL (assuming you have all the associations set up in your models). But, that's a personal preference. Where should I put my custom code when it doesn't fit into the model or controller?
The logical place to put it would be in the model, so I think having something like Order::import_from_excel
would be a good idea. Disclaimer: I'm an advocate of the fat model, slim controller philosophy, so other people might hold different opinions about this.
However, you should encapsulate the functionality into a seperate class in lib/
that gets instantiated and called from import_from_excel
. This helps testability, decreases coupling and will probably help you if the requirement to import other things from Excel arises in the future.
Is it okay to hit the database from a custom model binder?
I've decided to edit my original answer given my thinking on these types of things has evolved since early 2010.
In my original answer, I basically expressed that, while my instincts told me you shouldn't do this, I was uncomfortable saying we shouldn't without being able to articulate why.
Now, I'd recommend against this on the grounds that the responsibility of a Model Binder is to translate a user request into a Request Model and that retrieving data outside of what can be derived from the request goes beyond this scope of responsibility.
Related Topics
Ruby/Rails 3.1: Given a Url String, Remove Path
How to Find Word with The Greatest Number of Repeated Letters
Truncate String When It Is Too Long
How to Interact with a Caldav Server from Ruby
Problem with Vim's Ruby Plugin
Understanding The Behaviour of Inject Used with a Lambda in Ruby
What Hash Function Does Ruby Use
Why Can't The Mail Block See My Variable
Using a Self-Signed Certificate
Setting Up Configuration Settings When Writing a Gem
Shellwords.Shellescape Implementation for Ruby 1.8
Deleting a Specific Line in a Text File
In Ruby, Is Truthiness Idiomatic for a Method Name Ending with a Question Mark
Ruby-Open3.Popen3/How to Print The Output
How to Get All Message History from Hipchat for a Room via The API
How to Find Out What Is Intercepting 'Method_Missing'
Using Update_Columns in Rails 3
How to Send a Keep-Alive Packet Through Websocket in Ruby on Rails