Is it possible to share constants between controller and model?
e.g. in product.rb I have
PRODUCT_TYPES = %w[one two]
I want PRODUCT_TYPES constant to be available in the controllers as well.
As per my consideration your Product model looks like
class Product < ActiveRecord::Base
PRODUCT_TYPES = %w[one two]
end
You can access the given constant in the controller as below
p.product_type == Product::PRODUCT_TYPES[:one]
I deeply explained the various possibility in this answer
You basically have 3 possibilities:
global scope (initializer)
application scope (using the application module created by Rails)
class scope (defined them where you want, and call them with Class::CONSTANT)
We can access model constant in Controller as bellow...
class Invoice < ActiveRecord::Base
STATUS_PAYABLE = %w(APPROVED OPEN)
end
Controller use like ..
Invoice::STATUS_PAYABLE.include?('OPEN')
Related
I have a table in the model called pg_search_documents, how do I work with it in the controllers?
I'm trying like this:
def show
#search = PgSearchDocument.find(params[:content])
end
But the so-called "PgSearchDocument" seems to be wrong.
You need to make sure you have a model declared in your app. If you have not done so, create the following file:
app/models/pg_search_document.rb
class PgSearchDocument < ActiveRecord::Base
end
In Rails 5 you would use:
class PgSearchDocument < ApplicationRecord
end
Please note the following naming conventions in Rails:
Database table name is plural snake case: pg_search_documents
Model filename is singular snake case: pg_search_document.rb
Model class name is singular camel case: PgSearchDocument
I have two models in my rails app ConfirmRequest.rb and Booking.rb.
These models are associated with each other with this configration:
class ConfirmRequest < ActiveRecord::Base
has_one :booking
end
class Booking < ActiveRecord::Base
belongs_to :confirm_request
end
So, I want to define 2 variables first which contains the confirm_requests for which booking has been created and other for which booking has not been created How can I define these variable in rails ?
Try with the following queries:
ConfirmRequest.where(id: Booking.pluck(:confirm_request_id))
ConfirmRequest.where.not(id: Booking.pluck(:confirm_request_id))
Variable as in a class variable ? A scope can give you that data you may create a class variable which uses that scope(not required though, scope is sufficient IMO). If you want to define a scope in ConfirmRequest to return records for which Booking has been created ? In that case
scope :has_booking, where("booking_id IS NOT NULL)
For Booking not created
scope :has_no_booking, where(:booking_id => nil)
Some of my models has a column named "company_id".
I need that all querys in these models has a condition based in this column, so I can easily separate the companies rows.
Something like this:
Customer.where(state: x).`where(company_id: current_company)`...
How can I intercept this method to enforce this extra condition?
I would recommend using a concern to add this requirement as a default scope to all of your models.
module HasCompany
extend ActiveSupport::Concern
included do
default_scope { where(company_id: current_company) }
end
end
class Customer < ActiveRecord::Base
include HasCompany
...
end
Note: this approach will only work if you have access to current_company as a class method on your models.
Where does this code live? It looks like controller logic? If it's in a controller, then you can just set the current_company in a before_action in the application controller—probably like you're doing already. Presuming you have a has_many relationship between company and customers, you should just do current_company.customers.where(state: x).
If this code lives in a model, that's when things get tricky. You shouldn't have access to current_company in a model, since that deals with the current request.
In my Rails I have the following models:
A STI sub-class
class Subscription::Discount < Subscription
def self.new_with_url
...
end
end
and another model class (doing completely different things, this is a STI base class)
class Discount < ActiveRecord::Base
end
So in my controller, I uses Subscription::Discount when I create users:
#user.subscription = ::Subscription::Discount.new_with_url()
However it complains: undefined method 'new_with_url' for #<Class:0x007fbb499c6740>
I think Rails is not calling the right class with new_with_url. On top of that I am not sure what #<Class:0x007fbb499c6740> is. So, two questions:
Without renaming any model, how can I reference Subscription::Discount properly?
Why is the error message saying #<Class:0x007fbb499c6740>, I can understand if it is Discount instead of that anonymous class.
EDIT:
Here are all the relevant models:
app/model/discount.rb
app/model/coffee_discount.rb (CoffeeDiscount < Discount)
app/model/subscription.rb
app/model/subscription/discount.rb (Subscription::Discount < Subscription)
The method is named create_with_url but you're calling new_with_url.
Fix the method name.
I have a rails app with several models.
I have a function that I want to access from several models.
What's the best place to put this code and how can I make it accessible from the models that need to get at it?
My understanding is that helpers are just for views. Is this correct?
It seems wrong to create a plug-in and put it in the vendor folder - this is my code and integral to my app. Is this correct?
Thanks.
The simplest solution would be to create a module under lib and mix this into the models that need it, for instance, in lib/fooable.rb:
module Fooable
def do_foo
end
end
And then in your various models:
class MyModel < ActiveRecord::Base
include Fooable
end
No need to require fooable.rb, the Rails autoloading mechanism will find it for you as long as it's named using correct conventions.
In order to lessen the repetition of code, you could also create a main class which would include that module and the simply inherit from it from every model you'd like to share the behaviour.
Something like:
module Fooable
def do_foo
end
end
class ParentModel < ActiveRecord::Base
include Fooable
end
class Product < ParentModel end
class User < ParentModel end
class Item < ActiveRecord::Base end
Thus, in that example, both Product and User would share the do_foo functionality and Item would not.