Is is possible to use active storage with multi databases in rails? I have the following models:
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
class OtherRecord < ActiveRecord::Base
self.abstract_class = true
connects_to database: { writing: :other_db }
end
class SomeModel < OtherRecord
has_many_attached :files
end
I've added active storage migrations scoped to the secondary database and necessary tables were created there but ActiveStorage seems to look for tables in primary database. Have anyone a solution for that?
Related
I have a models like below
# Base model
class RecordBase < ActiveRecord::Base
self.table_name = 'records'
has_many :record_images, as: assetable, dependent: :destroy
fileuploads :record_images
end
# Inherited model
class SpecificRecord < RecordBase
end
# Image model
class RecordImage < ActiveRecord::Base
include Uploader::Asset
belongs_to :assetable, polymorphic: true
end
I'm using https://github.com/superp/rails-uploader for upload files. I have record of RecordImage model in database with assetable_id corresponding to SpecificRecord record and assetable_type 'SpecificRecord' but when I try SpecificRecord.find(some_id).record_images in console, rails builds sql query with assetable_type 'RecordBase' and hence finds nothing. How to specify which assetable_type should be in sql query?
Update
That's issue about rails-uploader gem, in version '0.2.8' gem redefined .base_class and saves data to db with assetable_type of child class, but in version '0.4.5' assets saves to db with assetable_type of base class.
I have a replica database slave running, where I want to send some readonly calls to, to offload the master. For this reason I would like to create two customs models, that connect separately to that database, so that I can use those, whenever I have the need to offload some queries.
I have two classes:
class Car < ActiveRecord::Base
has_many :prices
end
class Price < ActiveRecord::Base
belongs_to :car
end
Rails has the possibility to share custom database connections on model level like this:
class MyCustomDbConnection < ActiveRecord::Base
self.abstract_class = true
establish_connection({database: 'www.slavedb.com', port: 5432, pass: 'some'})
end
class ReadonlyCar < MyCustomDbConnection
end
class ReadonlyPrice < MyCustomDbConnection
end
While this works well, my use case is that I would ALSO like to have the ´ReadonlyCar´ and ReadonlyPrice inherit from the original models that uses the default ActiveRecord::Base.connection. This is needed to have the ReadonlyCar behave exactly like the original one Car (business logic). Now I can't do class inheritance from both ReadonlyCar < MyCustomDbConnection and ReadonlyCar < Carat the same time, so how do I get the full functionality from Car, but share the same connection to the slave between both ReadonlyCar and ReadonlyPrice?
You could write a module where in the included hook you do that call to establish the connection.
module MyCustomDbConnection
def self.included(base)
base.establish_connection(
database: 'www.slavedb.com',
port: 5432,
pass: 'some'
)
end
end
class ReadOnlyCar < Car
include MyCustomDbConnection
end
I'm attempting to have a parent model that other models inherit from, and a secondary class that has associations with the children from the first model. Here's what I have so far...
I used the first command to create the parent model.
rails g model Person name:string age:integer height:float
I then set up Person as the parent class, and two children class which inherit from it as seen below.
class Person < ActiveRecord::Base
self.abstract_class = true
end
class Driver < Person
self.table_name = "Driver"
belongs_to :vehicle
end
class Passenger < Person
self.table_name = "Passenger"
belongs_to :vehicle
end
I also set up a Vehicle class to use in an association with the Driver and Passenger children classes.
rails g model Vehicle color:string capacity:integer
class Vehicle < ActiveRecord::Base
has_one :driver
has_many :passengers
end
However, if I use the rails console and attempt to create a new instance Driver or Passenger, using Driver.new or Passenger.new, I encounter an PostgreSQL error.
For reasons which I cannot figure out, Rails is writing SQL statements to query on a Driver or Passenger table. However, it is my understanding that only one Person table is made and has a type attribute that is used for queries.
If anyone can offer some guidance here, I'd be very appreciative.
Thanks
Since it seems you're trying to use the common table persons for both Driver and Passenger, you don't need the abstract_class declaration, or the table_name declarations in either of the sub classes. Per the rails documentation, these options would be used when you want classes to inherit behavior from their parent, without the parent itself having a table.
The snippet below should work fine.
class Person < ActiveRecord::Base
end
class Driver < Person
belongs_to :vehicle
end
class Passenger < Person
belongs_to :vehicle
end
I am using concerns for my rails application. I've different kind of users so I have made a loggable.rb concern.
In my concern I have
included do
has_one :auth_info
end
because every of my user that will include the concern will have an association with auth_info table.
The problem is, what foreign keys I need to put in my auth_info table?
E.G
I've 3 kind of users:
customer
seller
visitor
If I had only customer, in my table scheme I would have put the field
id_customer
but in my case?
You can solve this with polymorphic associations (and drop the concern):
class AuthInfo < ActiveRecord::Base
belongs_to :loggable, polymorphic: true
end
class Customer < ActiveRecord::Base
has_one :auth_info, as: :loggable
end
class Seller < ActiveRecord::Base
has_one :auth_info, as: :loggable
end
class Visitor < ActiveRecord::Base
has_one :auth_info, as: :loggable
end
Now you can retrieve:
customer.auth_info # The related AuthInfo object
AuthInfo.first.loggable # Returns a Customer, Seller or Visitor
You can use rails g model AuthInfo loggable:references{polymorphic} to create the model, or you can create the migration for the two columns by hand. See the documentation for more details.
Since user has roles 'customer', 'seller', 'visitor'.
Add a column called role to Users table.
Add a column called user_id to auth_infos table.
class AuthInfo < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_one :auth_info
end
you can do
user = User.first
user.auth_info
Now you a additional logic to your concerns.
I've faced a trouble while implementing multiple database connections in a Rails 4 application. Along with the primary database connection I've created secondary connection by specifying details in database.yml.
secondary_base:
adapter: postgresql
encoding: unicode
host: localhost
database: secondary_db
pool: 5
username: postgres
password: postgres
Then created a model named SecondaryBase which holds the connection to that secondary database. Code given below:
secondary_base.rb
class SecondaryBase < ActiveRecord::Base
self.abstract_class = true
establish_connection "secondary_base"
end
Then added two models Member and Subdomain.
member.rb
class Member < SecondaryBase
has_and_belongs_to_many :subdomains
end
subdomain.rb
class Subdomain < SecondaryBase
has_and_belongs_to_many :members
end
Now as you can see that Member and Subdomain models are related by has_and_belongs_to_many relationship. So when I'm trying to insert data to the join table named members_subdomains, It's now working and giving me the error something like that PG: Undefined table, though the table exits in secondary_db database. What I understood that rails is trying to find the members_subdomains table in primary database.But when I tried the same code in Rails 3.2.13, then there were no problem at all, everything is fine. Have any of you deal with a similar problem before? Please help.
I believe you will need to switch from has_and_belongs_to_many to has_many :through to get this to work. In order to do that, just create a model for the join table - I'll call it `MemberSubdomain'.
class SecondaryBase < ActiveRecord::Base
self.abstract_class = true
establish_connection "secondary_base"
end
class MemberSubdomain < SecondaryBase
self.table_name = 'members_subdomains'
end
class Member < SecondaryBase
has_many :member_subdomains
has_many :subdomains, :through => :member_subdomains, :source => :subdomain
end
class Subdomain < SecondaryBase
has_many :member_subdomains
has_many :members, :through => :member_subdomains, :source => :member
end