I have hierarchical structure for model Board (implemented using ancestry gem).
Instead of one model and some scopes, I'd like to have two models: Board for root level elements (ancestry column value is nil), and Category for the rest(ancestry column value is not nil). They would be using the same table boards.
How can I do something like this?
You can explicity define a table for a model using set_table_name or self.table_name depending on your rails version. Also you can define a default scope for every query made for this model, using default_scope, so a combination of both should be what you are searching for:
class Category < AR:Base
self.table_name = 'boards'
default_scope where('boards.ancestry IS NOT NULL')
end
You could specify the table name of the category model and generate a default scope:
class Category < ActiveRecord::Base
self.table_name = "boards"
default_scope where('boards.ancestry IS NOT NULL')
end
And you should be able to interact with both models wit the boards-Table.
Or you stay with one model and add two modules for the specific stuff. That depends on your preferences.
Related
What are my options for molding existing database table(s) to my model in rails? I have a has_one and belongs_to relation between two tables, but I'd like to join them and use that as a model (and select only the fields relevant). As this is an external table I'd also like to minimize the amount of queries.
I am inheriting an existing app and would like to not touch anything from the existing environment and slowly migrate. The existing database seems to have been made different from the rails way. I have a model of IdCard and IdCardRequest. One would assume that one IdCard hasmany IdCardRequests, however the IdCard has a property to the last IdCardRequest. It seems that the basic info such as applicant_name is a property of the IdCardRequest rather than IdCard. Luckily they both have a common property id_card_number and I could join it based on that by specifying foreign_key and primary_key to id_card_number. However for now I'd like a model IdCard with the rest of the fields of the IdCardRequest as property.
class IdCard < ExternalTable
self.table_name = 'id_cards'
belongs_to :security_id_request, :foreign_key => 'request_id'
default_scope { includes(:id_request) }
end
class IdRequest < ExternalTable
self.table_name = 'id_request'
has_one :id_card, :foreign_key => 'request_id'
end
# I would like IdCard.first.applicant_lastname
# I have to call IdCard.first.id_request.applicant_lastname
# I have to call IdCard.first.id_request.applicant_firstname
# I could write a delegate_to for every property, but this seems cumbersome and inefficient.
Do you have the option of creating a database view that encapsulates both tables, and renames columns to rails conventions?
e.g.
create view id_card_requests as
select
existing_column as desired_rails_column_name,
...
from id_cards
join id_card_requests on <whatever the join is>
You can then make a rails model IdCardRequests that will work as normal. You can make one of the columns a primary key in the view, or tell the model to use one of the columns with self.primary_key = :my_key_column
I have this problem. I need to use an existing table on a mysql database. The name of the table is not compatible with RoR conventions and I need to remap the table name and the name of the attributes. I have created a scaffold to visualize on a web page the content of the table but I can't change the mapping. Is there a solution to indicate to RoR the relation between the name of the class and the name of the table in the database? and a solution to indicate the relation between the attribute of the class and field on the table?
Thanks.
The table name can be specified using table_name class method.
For the attributes/column, you need to explicitly specify aliases for the attributes using alias_attribute method. For example, if you have name_of_thing column, but want to treat it as name, then you need something like this in your model:
class CreateUtenti < ActiveRecord::Base
self.table_name = "another_name"
alias_attribute :name, :name_of_thing
end
Yes you can pass table name in model like:
class YourModel < ActiveRecord::Base
self.table_name = "pass_table_name_here"
end
I would like to create a list of model objects that designate a new relationship without having to use raw sql.
Suppose I have the following models:
class MealCombination < ActiveRecord::Base
belongs_to :drink
belongs_to :food
end
class Food < ActiveRecord::Base
has_many :meal_combinations
end
class Drink < ActiveRecord::Base
has_many :meal_combinations
end
I would like to create a list of MealCombination objects that do not presently exist in the database.
Say my query would look something like this:
select distinct DRINK.id, FOOD.id from FOOD, DRINK where DRINK.alchohol_volume > 5 and FOOD.spice_factor > 45;
What is the most efficient way to create the MealCombination objects from this selection?
Iterating through an array returned back from the raw sql seems inefficient. I do not want to persist the objects into the database.
The easiest way to do this would probably be to create a view called "meal_combinations" in your database which will represent your select query you want to do. ActiveRecord should treat the view as a table for the most part, but you should definitely add
def read_only?
true
end
to any class definition that uses a view. The main disadvantage to having a lot of views is that they make database migrations a little more of a pain to manage if you ever want to change columns in the underlying tables.
class CashOrderStatus < ActiveRecord::Base
belongs_to:cash_order
end
usually the db need a table cash_order_statuses to mapping this model,but now i want to
mapping this model to a specific sql view like
select * from order_statues where cash_order_id is not null <=> CashOrderStatus
does rails provide some way to achieve this
There are multiple ways to fulfill your requirement:
In your CashOrderStatus model, you can set table name to override default ORM mapping:
class CashOrderStatus > ActiveRecord::Base
set_table_name "order_statuses"
belongs_to:cash_order
end
You can implement STI(Single Table Inheritance) functionality where in your database table "order_statuses" one more column will be there: type which will hold the derived model class name(In this case, CashOrderStatus).
So your model will look like this:
class CashOrderStatus > OrderStatus
set_table_name "order_statuses"
belongs_to:cash_order
end
And OrderStaus model will be derived from AR::Base class. Try it.
NOTE: Sorry for the class inheritance notation. It should be < instead of >. There is formatting issue in my stackoverflow account, so I put like this :-)
I'm using a tool(UltraSms) that required three tables named (smsin, smsout & smsparts)
I need these tables to be used in the same Rails application that has other tables. With ActiveRecrod I know that table names has to be plural of the Active record class name by convention. Is there a way to map those to an ActiveRecrod class easily or should I find manual way to do ORM for it?
Thanks,
Tam
Seems that in Rails3.1 , the method name changed to table_name=, e.g.
class Mouse < ActiveRecord::Base
self.table_name = "mice"
end
You can do this:
class MyClass < ActiveRecord::Base
set_table_name "smsin"
end