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

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

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

Ruby Mongoid::Errors::InvalidField

class MyModule::MyModel
include Mongoid::Document
field :field1, :type=>Integer
...
field :fieldn, :type=>Integer
field :deleted, :type=>Boolean
store_in session: 'mydb', collection: 'mycollection'
end
These code threw Mongoid::Errors::InvalidField when came to :deleted definition. If I remove this line, it works well.
/var/lib/gems/2.1.0/gems/mongoid-4.0.0/lib/mongoid/fields/validators/macro.rb:56:in `block in validate_name': (Mongoid::Errors::InvalidField)`
As http://www.rubydoc.info/github/mongoid/mongoid/Mongoid/Errors/InvalidField says,
This error is raised when trying to create a field that conflicts with
an already defined method.
How can I use this conflicted name?
When I try to add a deleted field, Mongoid 4.0.2 says:
Problem:
Defining a field named 'deleted?' is not allowed.
Summary:
Defining this field would override the method 'deleted?', which would cause issues with expectations around the original method and cause extremely hard to debug issues. The original method was defined in:
...
When you say:
field :f
Mongoid creates three methods for that field: f (getter), f= (setter), and f? (is f truthy AFAIK). The last one is causing your problem because Mongoid has its own deleted? method.
Your best bet would be to use a different name for that field, field :is_deleted perhaps.
If you can't do that (i.e. you're attaching Mongoid to a predefined collection), then you could use dynamic attributes:
class MyModule::MyModel
include Mongoid::Document
include Mongoid::Attributes::Dynamic
field :field1, :type=>Integer
...
field :fieldn, :type=>Integer
# Don't define the field here
store_in session: 'mydb', collection: 'mycollection'
end
and then you'd access it use Mongoid's [] and []= methods:
d = MyModule::MyModel.new
d[:deleted] = true
d = MyModule::MyModel.find(id)
puts d[:deleted]
puts d.attributes['deleted']
You could also add your own is_deleted and is_deleted= methods that would use [] and []= to update the underlying attribute.

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

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
....

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

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.

Resources