How do I define my table owner/schema in my sequel class? - ruby

The table I'm trying to query is named is cache.dashboardstats
my model is:
class Dashboard < Sequel::Model(:dashboardstats)
set_schema do
set_primary_key :dashboardstatid
end
end
This creates a select * from "dashboardstats";
How do I define the owner/schema of "cache" so that my query becomes:
select * from cache."dashboardstats";

You can use a double underscore inside a symbol, or one of the qualify methods to represent a qualified identifier:
:cache__dashboardstats
Sequel.qualify(:cache, :dashboardstats)
:dashboardstats.qualify(:cache)
You would use this in your model code like:
class Dashboard < Sequel::Model(:cache__dashboardstats)
end
Note that I left out your set_schema call. You should never call set_schema unless you are calling create_table or a similar method, as otherwise it does nothing. set_primary_key inside set_schema doesn't do what you think, and Sequel can usually determine the primary key correctly, so it's not normally specified manually.

Related

ActiveRecord mapping to table name with schema name as prefix

Has anyone experienced this issue on mapping table in ActiveRecord when table name need a schema name as a prefix (oracle)?
Gemfile
gem 'activerecord', '4.2.4'
gem 'activerecord-oracle_enhanced-adapter', '1.6.7'
....
db_helper.rb
class Student < ActiveRecord::Base
self.abstract_class = true
self.table_name_prefix = 'OPT_ABC.'
self.table_name = 'STUDENT'
def self.list_student
puts Student.take(1) #testing
end
end
The actual table name looks like:
SELECT * FROM OPT_ABC.STUDENT;
I am able to connect to the database instance, but when the code gets line:
puts Student.take(1) # SELECT * FROM STUDENT LIMIT 1
I get the following error:
ActiveRecord::StatementInvalid:
table or view does not exist: SELECT "STUDENT".* FROM "STUDENT"
I am looking for solution on how to handle 'OPT_ABC." table prefix. Please share your solution.
It looks like the problem is that you're trying to use both self.table_name_prefix= and self.table_name= together when you should be using one OR the other.
First let's consider how both self.table_name_prefix= and self.table_name= work.
self.table_name_prefix=
According to the documentation, self.table_name_prefix= works by prepending the passed in value to the table name that ActiveRecord automatically generates based off of the name of the class.
So, if the class name is Student and you do self.table_name_prefix = 'OPT_ABC.', your table name will be OPT_ABC.STUDENTS. Note that the generated table name is plural (and ends in an s).
self.table_name=
According to the documentation, self.table_name= sets the table name explicitly. This means that it completely overrides the table name to the value that you pass in.
So, if you do self.table_name = 'OPT_ABC.STUDENT' your table name will be OPT_ABC.STUDENT.
So, given that, to set the table name to OPT_ABC.STUDENT, you should be able to simply pass the value into self.table_name like this:
class Student < ActiveRecord::Base
self.abstract_class = true
self.table_name = 'OPT_ABC.STUDENT'
def self.list_student
puts Student.take(1) #testing
end
end

Make friendly_id scope play nice with subclassed ActiveRecord model

I have a subclassed ActiveRecord model which uses a separate table to store records and friendly_id (4.1.0.beta.1) to generate slugs. Problem is friendly_id is using the parent class's table to check for existing slugs, instead of using the child table. Basically I'd like friendly_id to scope its checks to the right table.
Example:
class Parent
friendly_id :name, :use => :slugged
end
class Child < Parent
self.table_name = 'children'
end
Parent.create(name: 'hello').slug
> 'hello'
Child.create(name: 'hello').slug
> 'hello--2'
I want friendly_id to generate the 'hello' slug for the second create, because there are no records in the children table with that slug. Is there a way to configure or monkey patch the class friendly id uses for its queries?
EDIT: added friendly_id version for future reference
I'm posting my own solution to this problem, just in case someone is having the same problem. I should reiterate that this problem was found on version 4.1.0.beta.1 of the friendly_id gem (which at the time was the most recent version), so this issue may not occur any more.
To solve this problem, I basically configured slug_generator_class to use my own class, so I could monkey patch the culprit method.
In my model:
friendly_id do |config|
config.slug_generator_class = SubclassScopableSlugGenerator
end
In an initializer, I overrode the FriendlyId::SlugGenerator.conflicts method so I could access the sluggable_class var:
# Lets a non-STI subclass of a FriendlyId parent (i.e. a subclass with its
# own dedicated table) have independent slug uniqueness.
class SubclassScopableSlugGenerator < FriendlyId::SlugGenerator
private
def conflicts
# this is the only line we're actually changing
sluggable_class = friendly_id_config.model_class
pkey = sluggable_class.primary_key
value = sluggable.send pkey
base = "#{column} = ? OR #{column} LIKE ?"
# Awful hack for SQLite3, which does not pick up '\' as the escape character without this.
base << "ESCAPE '\\'" if sluggable.connection.adapter_name =~ /sqlite/i
scope = sluggable_class.unscoped.where(base, normalized, wildcard)
scope = scope.where("#{pkey} <> ?", value) unless sluggable.new_record?
length_command = "LENGTH"
length_command = "LEN" if sluggable.connection.adapter_name =~ /sqlserver/i
scope = scope.order("#{length_command}(#{column}) DESC, #{column} DESC")
end
end

Ruby Datamapper model wrapped around a module prefix module name in the table name in sql query

I have a datamapper model as:
module abc
class Post
include DataMapper::Resource
property :title, String
property :body, Text
end
end
Note, my class is wrapped around module abc
In other file
I have:
abc::Post.all
This should make call to query:
select * from posts
But it calls
select * from abc_posts
Table name get a prefix added abc_ . How can I remove it. I don't keep model around the module, then it works as expected. But my codebase needs model to be inside the module.
I found the solution at http://rubydoc.info/github/datamapper/dm-core/master/DataMapper/NamingConventions/Resource/UnderscoredAndPluralizedWithoutModule
repository(:myreponame).adapter.resource_naming_convention = DataMapper::NamingConventions::Resource::UnderscoredAndPluralizedWithoutModule
change :myreponame
Also at http://datamapper.rubyforge.org/dm-core/DataMapper/NamingConventions.html
You can also set your storage name(s) explicitly:
http://datamapper.org/docs/legacy.html

Specify column for model attributes in Rails3?

Is it possible to specify the column for an attribute? I have something like:
NAME, COUNTRY
The database is quite large and I have over a thousand columns which are capitalized like this. I want to refer to them as so:
attr_accessible :name, :country
Where :name = column NAME. I'd prefer Model.name rather than Model.NAME. It isn't possible to downcase every column name in the structure file.
Here is an idea to do the way you preferred.
Command to generate migration: (In my example, im applying this on Posts table. Change according to your table name)
rails g migrate RenameColumnsOfPosts
Below is the migration up method. Here taking all the column names and for each one I'm applying rename_column to make it downcase.
class RenameColumnsOfPosts < ActiveRecord::Migration
def up
Post.columns.map(&:name).each do |column_name|
rename_column(:posts, column_name, column_name.downcase)
end
end
def down
#You can do the opposite operation here. Leaving on you
end
end
As i didnt run it personally, it might need some changes. So start with it and let me know if facing any problem.
Please write code inside of model ,
it's just for demostration code,after you get it and update as per logic :
This Code inside of model :
...
attr_accessor :name,:country
before_save :fill_save
..
#assign variable like ...
def fill_save
self.NAME= self.name
self.COUNTRY= self.country
end
....

Can't display more than one table model inheriting from the same class on different tables in QtRuby

I've been following this article to display ActiveRecord data in QtRuby. I've copied the BoatTableModel class from there(used my own code for the rest). In the article, BoatTableModel is defined to only support the Boat model, but except for the column definitions the code is quite generic. So, I've changed it so instead of having the columns defined there, I've made it take the columns from a column_names method, and define that methods in subclasses for each model.
Here is my code:
class QtArModel<Qt::AbstractTableModel
def initialize(items)
super()
#items=items
end
def rowCount(parent=nil)
#items.size
end
def columnCount(parent=nil)
column_names.length
end
def data(index,role=Qt::DisplayRole)
invalid=Qt::Variant.new
return invalid unless role==Qt::DisplayRole or role==Qt::EditRole
item=#items[index.row]
return invalid if item.nil?
v=item[column_names[index.column]]||""
return Qt::Variant.new(v)
end
def headerData(section,orientation,role=Qt::DisplayRole)
invalid=Qt::Variant.new
return invalid unless role==Qt::DisplayRole
v=case orientation
when Qt::Horizontal
column_names[section]
else
""
end
return Qt::Variant.new(v.to_s)
end
def flags(index)
return Qt::ItemIsEditable|super(index)
end
def setData(index,variant,role=Qt::EditRole)
if index.valid? and role==Qt::EditRole
s=variant.toString
item=#items[index.row]
if index.column.between?(0,column_names.length-1)
item[column_names[index.column]]=s
else
raise "invalid column #{index.column}"
end
item.save
emit dataChanged(index,index)
else
return false
end
end
end
class QtCoursesTableModel<QtArModel
def column_names
return [
:number,
:name,
:tutor_name,
:site,
:active,
]
end
end
class QtTasksTableModel<QtArModel
def column_names
return [
:course,
:ex_number,
:received,
:due,
:description,
:link,
:completed,
:file,
]
end
end
Now, when I display one model(doesn't matter which) - everything works just fine. However, when I display both models, each in it's own Qt::TableView - only the first one is displayed, and the other table view is blank.
I've tried different ordering, and the table that gets to display it's data is always the one which it's Qt::TableView is created first - the order of the creating the Qt models does not matter. Also, when I create the model object for the first table, but don't actually set it's model property to it, the second table displays it's data.
I've also tried to display the same model twice in two different table views - and it worked - for a split second, and then the second view's data disappeared.
I've also tried to copy-paste the QtArModel, change it's name, and make one of the models inherit from the copy. That did work - but it's obviously a huge code duplication, so I would really like to avoid that.
Now, my guess is that something in QtArModel is defined as a class member instead of instance member, making both model instances share something they shouldn't share. It has to be in QtArModel - because if it was higher in the inheritance tree, the problem would have remained when I've duplicated QtArModel. However, I can't find anything in my QtArModel that's class-scoped instead of instance-scoped.
What am I missing?
OK, I've managed to work this out. Apparently, the problem was not the inheritance, but the GC. Since the only connection to the models was from TableView's model property - which is just a wrapper for C++ getter and setter - ruby thought it lost the reference to my models, and GC'd them.
Solved by keeping the models in ruby variables.

Resources