How do I create a Rails model in a different DB schema? - ruby-on-rails-3

I have a Rails 3.2 app backed by MS SQL 2008. All its models are by default created in dbo schema. Now I want to have a model which DB table has limited access to it so I want to put it to a different DB schema. How do I do that?

Turns out you can just define it together with table name:
def change
create_table "schema_name.table_name" do |t|
#init table
end
end

Don't forget to add schema_search_path: 'schema1,schema2' to the database.yml.

Related

How to create database table when using Wildfly?

I am trying to complete a tutorial on a simple javaEE project using wildfly. The first step is creating two tables in my database. As it says I should create my tables like this: "CREATE TABLE wildfly.name...." but it gives me an error saying thet wildfly is unknown.
Link to the tutorial: click here
My question is why should i put "wildfly." before the table name and how can I solve this error?
Thank you for your help!
Note: I am using oracle database instead of mysql
It's a misleading MySQL tutorial example because in Oracle syntax "wildfly." is a user(schema) in the Oracle database.
Schema/user in Oracle is a namespace for tables and other objects. So, when you issue such a statement - you're telling oracle to create table in namespace WILDFLY. If you don't have such user in your database or you don't have rights to access such user/schema - you can't create tables there.
You should create such user in Oracle database (or alter your statement to another user/schema name that you actually have in your database) and put your tables there.
For example these statements are correct because I created WILDFLY user before putting tables to it:
CONNECT SYS/****#ORCL AS SYSDBA
CREATE USER WILDFLY IDENTIFIED BY WILDFLYPASSWORD;
GRANT UNLIMITED TABLESPACE TO WILDFLY;
CREATE TABLE WILDFLY.MYTABLE...

Is it possible to alter schema of a database I am not connected to?

Is it possible to alter schema of a database I am not connected to? More specifically I need to change an owner of a schema (but it doesn't matter for the questions' sake).
As documentation says schemata can be altered using a clause like:
ALTER SCHEMA name OWNER TO { new_owner | CURRENT_USER | SESSION_USER }
and it sure works, but only on a database I am currently connected in.
Sure I can reconnect to the other database and do it manually, but I am interested whether it is possible to do it from a connection to another (typically postgres) database. It would be quite helpful for automation processes.
I have tried something like:
ALTER DATABASE ALTER SCHEMA name OWNER TO ...
ALTER SCHEMA "db_name".name OWNER TO ...
But without success - so I am interested whether it is possible at all.
I tried to search for this information using one popular search engine and StackOverflow search feature as well. Unsuccessfully - hence the question.
As #a_horse_with_no_name and #JacobH pointed out in comments it is not possible to alter schema of a database you are not currently connected to.
So I ended up using a command like this in order to achieve the schema alteration:
psql $PG_DATABASE -c "ALTER SCHEMA \"<schema-name>\" OWNER TO $PG_USER";

Synonym support on PostgreSQL

How to create and use Synonyms on PostgreSQL as in Oracle. Do I need to create some DB link or any thing else. I could not find any good official doc on this topic.
Edit 1
Actually as of now i have an application which has two separate modules which connects with two different oracle databases; One modules need to access tables of other so for which we use synonyms over db link in oracle. Now we are migrating application to postgresql, so we need synonyms.
Edit 2
When i say two different oracle databases it means it can be two different oracle instances or two schemas of same db, it is configurable in application and application must support both modes.
PostgreSQL version: 9.6.3
Approach 1:-
Finally i got it working using foreign data wrapper postgres_fdw as below
I have two databases named dba and dbb. dbb has a table users and i need to access it in dba
CREATE SERVER myserver FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'localhost', dbname 'dbb', port '5432');
CREATE USER MAPPING FOR postgres
SERVER myserver
OPTIONS (user 'user', password 'password');
CREATE FOREIGN TABLE users (
username char(1))
SERVER myserver
OPTIONS (schema_name 'public', table_name 'users');
CREATE FOREIGN TABLE users (users char(1));
Now i can execute all select/update queries in dba.
Approach 2:-
Can be achieved by creating two schemas in same db, below are the steps:
create two schemas ex app_schema, common_schema.
Grant access:
GRANT CREATE,USAGE ON SCHEMA app_schema TO myuser;
GRANT CREATE,USAGE ON SCHEMA common_schema TO myuser;
Now set search path of user as below
alter user myuser set search_path to app_schema,common_schema;
Now tables in common_schema will be visible to myuser. For example let say we have a table user in common_schema and table app in app_schema then below queries will be running easily:
select * from user;
select * from app;
This is similar to synonyms in oracle.
Note- Above queries will work PostgreSQL 9.5.3+
I think you don't need synonyms in Postgres the way you need them in Oracle because unlike Oracle there is a clear distinction between a user and a schema in Postgres. It's not a 1:1 relationship and multiple users can easily use multiple schemas without the need to fully qualify the objects by exploiting Postgres' "search path" feature -  mydb.public.mytable.
If the tables are supposed to be in a different database in PostgreSQL as well, you'd create a foreign table using a foreign data wrapper.
If you used the Oracle synonym just to avoid having to write atable#dblink, you don't have to do anything in PostgreSQL, because foreign tables look and feel just like local tables in PostgreSQL.
If you use the synonym for some other purposes, you can either set search_path to include the schema where the target table is, or you can create a simple view that just selects everything from the target table.

Rails Associations and Migration

I am attempting to create a journal where a logged in user's journal_entries are listed when the index view is called.
I have installed the Devise gem for the user sign up, log in/out authentication.
I have created a model, JournalEntries, which includes a date, string and text fields.
After creating the database, rake db:create and then migrating, rake db:migrate - I attempted to list a users journal entries in the journal_entries/index view. The default view that was derived via scaffolding lists ALL USERS journal_entries. This doesn't make for a great journal - where you can see the entries of all other users.
In my research I've come to realize that I didn't have a field in the journal_entries table which referenced the users table.
I create a migration show below:
class AddForeignKeyToJournalEntries < ActiveRecord::Migration
def up
change_table :journal_entries do |t|
t.references :user
end
#add a foreign key
execute <<-SQL
ALTER TABLE journal_entries
ADD CONSTRAINT fk_journal_entries_users
FOREIGN KEY (user_id)
REFERENCES users(id)
SQL
end
def down
execute <<-SQL
ALTER TABLE journal_entries
DROP FOREIGN KEY fk_journal_entries_users
SQL
end
end
(I also changed the users.rb and journal_entries.rb models to include belongs_to and has_many association - at first I thought this is all I had to do, and somehow the database would pick this up, but it didn't...)
This successfully added foreign key - user_id to the journal_entries table, and I thought I was in the clear.
What is happening now is when a journal_entry is created - the user_id column is blank - no info is being populated there....? I have verified this by logging into Postgres on my local machine.
Any help would be greatly appreciated!
The reason the user_id column is blank in the journal_entry table is because you need to add the current user's id when a new journal entry is created.
In your JournalEntries Controller you'll need to add this to your create action:
#journal_entry.user_id = current_user.id
or, #journal_entry.user = current_user
Then, in your JournalEntries Controller index action:
Instead of #journal_entries = JournalEntry.all you can display only the current logged in user's entries with #journal_entries = current_user.journal_entries.
Hope that helps!
You need to make sure that when you build a new instance of the JournalEntry that it has knowledge of the association with the current user:
# app/controllers/journal_entries_controller.rb
...
def create
#journal_entry = current_user.build_journal_entry(params[:journal_entry])
...
See the relevant part of the Rails Guide for Active Record Associations.

Drop or Delete Schema Postgresql via controller Rails

I have multi-tenant application rails with postgresql,
i want to drop schema (schema name = subdomain) and delete or table on schema.
primitive code on controller, wkwkwk.
accounts_controller.rb
def destroy
#account = Account.find(params[:id])
conn = ActiveRecord::Base.connection
conn.execute("DROP SCHEMA "+#account.subdomain)
end
error message
ActiveRecord::StatementInvalid in AccountsController#destroy
PG::Error: ERROR: cannot drop schema subdomain1 because other objects depend on it
DETAIL: table articles depends on schema subdomain1
table gambarinfos depends on schema subdomain1
table pages depends on schema subdomain1
table redactor_assets depends on schema subdomain1
table schema_migrations depends on schema subdomain1
table usersekolahs depends on schema subdomain1
HINT: Use DROP ... CASCADE to drop the dependent objects too.
: DROP SCHEMA subdomain1
any ideas?
thx
problem solved with
add CASCADE to conn.execute("DROP SCHEMA "+#account.subdomain+" CASCADE")