how to change the order of columns - ruby-on-rails

I got the data by 'MODEL.all' command in rails console
I want to put the column 'cgi_name' in the 3rd position when I run MODEL.all in the rails console
I use the postgres for my DB
How to get it ?

To answer your question directly, you'll have to move the columns at DB level
Currently, I only know MYSQL to support this functionality:
ALTER TABLE Employees CHANGE COLUMN empName empName VARCHAR(50) AFTER department;
Postgres, to my knowledge, does not support this functionality:
Many people new to postgresql often ask if it has support for altering
column positions within a table. Currently it does not; if you want to
change column positions, you must either recreate the table, or add
new columns and move data
In the view, you'll have to either manually display the columns, or create a helper method to cycle through them in an order of your choosing

Simple answer is YOU CANNOT
There is no way to re-order the column names to be displayed when you select using Model.all.
Otherwise, you can re-order this by selecting each column in the order you want.
Model.select("column1, column2, cgi_name, column4 etc..")
Hope it helps :)

Related

How to delete specific table's column using FMDB?

I am trying to delete column last_name from Persons using FMDB,
let query = "ALTER TABLE Persons DROP COLUMN last_name;"
try FMDBHelper.database.executeUpdate(query, values: nil)
But comes with error
DB Error: 1 "near "DROP": syntax error".
sqlite does not support DROP COLUMN in ALTER TABLE.
You can only rename tables and add columns.
If you need to remove columns, create a new table, copy the data there, drop the old table and rename the table to its intented name.
Reference: http://www.sqlite.org/lang_altertable.html
Please note that I flagged that your question could be duplicated, I will provide an answer to make it more clear.
I think that you are missing a point, which is: The FMDB is (as mentioned in their repo description):
This is an Objective-C wrapper around SQLite
Keep in mind that since FMDB is built on top of SQLite, it is not a limitation from the library itself; it is related to how SQLite ALTER TABLE works.
The SQLite ALTER TABLE statement is limited to rename a table and add a new column to the desired table:
SQLite supports a limited subset of ALTER TABLE. The ALTER TABLE
command in SQLite allows the user to rename a table or to add a new
column to an existing table.
http://www.sqlite.org/lang_altertable.html
For achieving what are you looking for:
You could check the answers of Delete column from SQLite table.

How to get right values from array thats values are in other table

I have the list of records saved as array in database like below:
---
- '9'
- '10'
- '11'
These are saved in option_ids column in table.
I have another table in which they all are present like below.
What I need to do is to print the values text like speak well if its id is present in options_ids column. So, what will happen is, if options_ids contains 9,10,12 etc so we will print data from other rows table like speak well, read well, listen well.
Assuming your "other table" is class OtherTable and assuming your fourth column is called text then you'd want to do
options_ids.map{|option| OtherTable.find(option).text}.join(', ')
When using rails you should take advantage of Active Record Associations.
I guess that a user(?) can choose different options from that second table.
The association would be a has_and_belongs_to_many-relation.
A good read is this section in the rails guide: http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association
Basically you set up a join table between users and options and tell the two models that they have a has_and_belongs_to_many-relation with each other.
Then when you fetch a user you can simple call user.options and it shows the options that are related to that user object.

How can I make an INT field in rails that starts to auto_increment at 10001?

How can I create a field (non-primary id) in a rails table that auto_increments like an id but that starts from the number 10,000? My app is using sqlite3 and rails 4.
Thank you
The suggested solution does not address my question. I was looking for a raw SQL answer.
If you had two auto increment columns on one table both value would always be in sync (with an offset given by the start value). Therefore it doesn't make much sense to have two independent auto increment columns on one table. It would just be a waste of diskspace.
That said: Some database engines support combined auto increment columns (auto increment columns that depend on other columns), but afaik no engine support two independent columns.
A simple work around would be something like this:
def secondary_id
id + 10_000
end

2 column table, ignore duplicates on mass insert postgresql

I have a Join table in Rails which is just a 2 column table with ids.
In order to mass insert into this table, I use
ActiveRecord::Base.connection.execute("INSERT INTO myjointable (first_id,second_id) VALUES #{values})
Unfortunately this gives me errors when there are duplicates. I don't need to update any values, simply move on to the next insert if a duplicate exists.
How would I do this?
As an fyi I have searched stackoverflow and most the answers are a bit advanced for me to understand. I've also checked the postgresql documents and played around in the rails console but still to no avail. I can't figure this one out so i'm hoping someone else can help tell me what I'm doing wrong.
The closest statement I've tried is:
INSERT INTO myjointable (first_id,second_id) SELECT 1,2
WHERE NOT EXISTS (
SELECT first_id FROM myjointable
WHERE first_id = 1 AND second_id IN (...))
Part of the problem with this statement is that I am only inserting 1 value at a time whereas I want a statement that mass inserts. Also the second_id IN (...) section of the statement can include up to 100 different values so I'm not sure how slow that will be.
Note that for the most part there should not be many duplicates so I am not sure if mass inserting to a temporary table and finding distinct values is a good idea.
Edit to add context:
The reason I need a mass insert is because I have a many to many relationship between 2 models where 1 of the models is never populated by a form. I have stocks, and stock price histories. The stock price histories are never created in a form, but rather mass inserted themselves by pulling the data from YahooFinance with their yahoo finance API. I use the activerecord-import gem to mass insert for stock price histories (i.e. Model.import columns,values) but I can't type jointable.import columns,values because I get the jointable is an undefined local variable
I ended up using the WITH clause to select my values and give it a name. Then I inserted those values and used WHERE NOT EXISTS to effectively skip any items that are already in my database.
So far it looks like it is working...
WITH withqueryname(first_id,second_id) AS (VALUES(1,2),(3,4),(5,6)...etc)
INSERT INTO jointablename (first_id,second_id)
SELECT * FROM withqueryname
WHERE NOT EXISTS(
SELECT first_id FROM jointablename WHERE
first_id = 1 AND
second_id IN (1,2,3,4,5,6..etc))
You can interchange the Values with a variable. Mine was VALUES#{values}
You can also interchange the second_id IN with a variable. Mine was second_id IN #{variable}.
Here's how I'd tackle it: Create a temp table and populate it with your new values. Then lock the old join values table to prevent concurrent modification (important) and insert all value pairs that appear in the new table but not the old one.
One way to do this is by doing a left outer join of the old values onto the new ones and filtering for rows where the old join table values are null. Another approach is to use an EXISTS subquery. The two are highly likely to result in the same query plan once the query optimiser is done with them anyway.
Example, untested (since you didn't provide an SQLFiddle or sample data) but should work:
BEGIN;
CREATE TEMPORARY TABLE newjoinvalues(
first_id integer,
second_id integer,
primary key(first_id,second_id)
);
-- Now populate `newjoinvalues` with multi-valued inserts or COPY
COPY newjoinvalues(first_id, second_id) FROM stdin;
LOCK TABLE myjoinvalues IN EXCLUSIVE MODE;
INSERT INTO myjoinvalues
SELECT n.first_id, n.second_id
FROM newjoinvalues n
LEFT OUTER JOIN myjoinvalues m ON (n.first_id = m.first_id AND n.second_id = m.second_id)
WHERE m.first_id IS NULL AND m.second_id IS NULL;
COMMIT;
This won't update existing values, but you can do that fairly easily too by using with a second query that does an UPDATE ... FROM while still holding the write table lock.
Note that the lock mode specified above will not block SELECTs, only writes like INSERT, UPDATE and DELETE, so queries can continue to be made to the table while the process is ongoing, you just can't update it.
If you can't accept that an alternative is to run the update in SERIALIZABLE isolation (only works properly for this purpose in Pg 9.1 and above). This will result in the query failing whenever a concurrent write occurs so you have to be prepared to retry it over and over and over again. For that reason it's likely to be better to just live with locking the table for a while.

Delphi - TUpdateObject versus OnUpdateRecord for a join SQL statement

I have a pFibdataset(which is working similar to BDEDataset) in which I need to make the following join selection
select table.Name as name,
table1.Name as name_1,
table2.Name as name_2
from table
left join table table_1 on table.id=table_1.id
left join table table_2 on table.id=table_2.id
Fields name, name_1 and name_2 are linked to some data-aware edits. Now, I want after I'm modifying(update,delete,insert operations) the name,name_1 and name_2 fields to be updated in the tables. Based on the wiki Using_Multiple_Update_Objects_Index I can use UpdateObjects, or OnUpdateRecord event.
The problem is that I don't understand how this need to be implemented. I have the join select on the query, how I need to define and work with name_1 and name_2 fields. Can someone provide me an example for this?
I know how to use subqueries in order to accomplish this. I need to see how can I can make it by using UpdateObjects or OnUpdateRecord.
TpFibUpdateObject works like a trigger on client side. To make it work, set the following properties:
DataSet - dataset (master) to monitor
KindUpdate - Insert/Update/Delete - action to monitor
SQL - command to execute when action is fired, params are taken from DataSet
ExecuteOrder - AfterDefault/BeforeDefault - probably you need after / master
BUT, instead using a lot of UpdateObject components and such tangled approach, I recommend two alternative (read better) ways:
Updatable view. It will work like a "virtual table". Create a view that joins these theee tables and write Before Insert/Update/Delete triggers. In Delphi use it as a regular table: select from view / insert into view / update view and delete from view. Anyway I suppose you need in many places these tables linked toghether.
Use EXECUTE BLOCK statements in your TpFIBDataSet SQLs. Insert / Update / Delete in a batch all tables.
Solution : OnUpdateRecord it must be created an TUpdateObject for each field from the joined table.
UpdateObjectvariable.DataSet := Dataset;
fill the SQL text
Apply.
After all update objects are set, UpdateAction := uaApplied; must be called.

Resources