How do I add a column that points to another table in a Rails database? - ruby-on-rails

Let's say I currently have a table titled "Report" and within Report, there are a bunch of strings, integers, timestamps, etc.
Now, I want to somehow be able to see who is currently working on a certain report - all I need are names, but the key is it could be more than one name so just adding a string column to the Report table wouldn't work. Plus, the names would keep changing - at one point, "Steve" and "John" could be working on a report, but once "Steve" stops, I need to be able to get rid of his name from the table.
I have a feeling that the correct way to do this is by:
creating a new table titled "Viewers" and having just one string field (for the person's name) in there. I'd add rows to this table when a new viewer is detected.
linking to indices within the Viewers table from the Report table. When a person stops viewing the report, the respective index is destroyed.
I think that makes sense logically, but I'm hesitant to implement this without being sure that this is the way to go. Any help/feedback/suggestions would be appreciated!
Edit:
I created a model for my join table and it auto-generated a migration and added an integer "viewer_id" and an integer "report_id" like Vimsha suggested below. However, I can't correctly implement the join tables in my code for some reason - when I want to add to the new Table (report_viewers), I say:
#viewer = ReportViewer.new
#viewer.viewer_id = get_current_user[:id]
#viewer.report_id = this_report.id
#viewer.save
However, when I access the table via
ReportViewer.where(:report_id => my_report.id).last.viewer_id.name (the viewer table has a string name)
it gives me a nil class. Do you know why?

Looks like you need a join table report_viewers
report_viewers
-report_id
-viewer_id
When you detect a new viewer, add an entry with report_id and viewer_id.
Remove the record if the viewer stops viewing the report.

What i usually do is use
rails generate migration addviewertoreport
and then just add the relevant commands

Related

Passing a Collection from VBA to a form

I have a an MS Access database with nine tables. The main form will be driven by a query linking the two main tables. When I pull up any one record ("family within a house"), I have a lot of variable data to pull into the form (how many family members, names of each, other specific information) to retrieve from the other seven tables. I created a VBA module, linked to this form, which is triggered when a record is loaded. The code aggregates all the family member data into a Collection of "person" elements. All of that works, as evidenced by the "Immediate" window in VBA. The "person" object is defined as a Class Module with all the relevant attributes (firstname, lastname, email, is-parent/is-child, etc).
Where I'm stuck: how do I access the collection within the form, so I can start populating elements? I haven't been able to find any documentation to do this, nor any similar questions asked/answered online. Next step will be creating all the elements dynamically, but right now, being able to create a static element and setting the control source to (at least some component/value within) the collection would be a huge help.
My VBA form module has a method, "Private Sub Form_Current()", which generates the collection when the current record is changed.
Thanks in advance...
Got my answer: "you don't". Set the element values in code, rather than trying to pass the collection the form.

How to assign foreign key in a master detail relationship using generator in Delphi XE2?

As an example:
I have two tables in firebird:
TB_CUSTOMER
IDCUSTOMER (autoincrement generator)
CUSTOMERNAME
TB_PHONE
IDPHONE
IDCUSTOMER (foreing key from TB_CUSTOMER)
PHONE
I have a registration form developed in Delphi. The table data TB_PHONE are handled using a dbgrid. I can not assign the value of the field IDCUSTOMER in TB_PHONE, because it was not generated by the Firebird generator. How can I make the relationship between the tables? I want to implement it without first saving the table data TB_CUSTOMER. I'm using datamodules with IBDAC.
Any sugest?
Before detail table can be inserted into, you should have PK-index over master-table updated and having proper master-ID in it. That means that some piece of code should insert master-record before inserting detail-record. Where this piece of code would be - is only limited by your fantasy.
Few arrangements include
insert the master-row in your application. Read the id of the row. Insert detail-row using this id.
read ID from then Generator, then insert both rows (master 1st) using the obtained ID
create a stored procedure, inserting both rows and returning ID (implementing #1 or #2 server-side)
use EXECUTE BLOCK - basically ad hoc anonymous SQL procedure. But that only is available in FB 2.x and except for not using namespace it is inferior to #3.
add BEFORE INSERT trigger onto detail table, searching for ID in master and adding one if not found. This would slow down all insert operations (even when master-ID already exists - that should be checked), would not be able to fill all other master columns but ID and is potentially dangerous due to hiding application logic problems. But still that can be implemented (though ugly and dirty method)
create master-join-detail VIEW and add INSERT trigger for it, propagating the new view-row into both master-table and details-table.
et cetera
I want to implement it without first saving the table data TB_CUSTOMER
There's your problem. You need the primary key from the master table before you can save the detail. That's just the way it works. But if what you want is to make sure that the values get saved together, you can do that as a transaction. In Firebird, you can do it like this:
Begin a transaction. Exactly how you do that depends on which DB library you're using to access your Firebird database.
Run an INSERT INTO ... RETURNING statement to insert the row into your master table and retrieve the generated value as a single operation.
Use the generated PK value to fill in the FK value on your detail table.
Insert the detail row.
Commit the transaction.

Facultative relation with Doctrine ORM

How should be implemented facultative one-to-one relation in Doctrine ORM and Symfony? Suppose there are some folders represented in database. Each folder can have a default icon or some custom icon represented in another table. How should this relation be described in the schema file? How can I tell that in case of given folder relation does or doesn't occur?
I myself have to guesses, but each seems to be not quite good:
1) Let's say I define folder_icon table with id column and folder_icon_id column in folder table and link these columns with foreign key. If folder_icon_id contains NULL, relation doesn't occur. If it contains some integer value it points to respective folder icon. When I implement it this way and try to obtain folder icon using something like $folder->getFolderIcon(), I get an instance of FolderIcon class with fields set to null (where I would rather excpect to get something like NULL, FALSE or Doctrine_Null). Why is it so? How should I check if the returned object is not 'real' folder icon?
2) Let's assume that I use method similar to previous but I define first row of folder_icon table to be the default icon, so that each folder that doesn't have any custom icon selected is related to this first row. In this case there is no problem with getting some dummy instances of FolderIcon class. But there is a problem if custom folder icon is removed form database, as there is no onDelete behaviour 'SET 1' to relate any folders using the deleted icon with the default icon.
How should this problem be solved? What is the proper way to define this kind of relation in schema file?
The problem is with the magic methods getVariable
Use $folder->folder_icon and to test for an existence of that relationship use isset(). Have a read of the doctrine website docs about testing for the existence of a relationship, I'm currently mobile so unable to link to it.

Showing many tables in many dropdown lists. c#, asp.net-mvc, linq2sql

I want to use an example to explain what I want.
Assume I've following DB design:
Item (id, name, categoryID);
Category (id, name);
When user wants to create an Item (fill in form), I'll give a list of categories in a dropdownlist, and when user chooses one of the categories ASP.NET MVC will automatically bind categoryID, to the selected one. I need to present same dropdown list when editing the item with correct selected one.
Question:
But my DB is very big, and it requires around 30-40 (maybe even more) category-like tables, that contain just "id" and "name", and all tables need to be shown in dropdown list while creating some other object, and also needs to be presented while editing the object. Definitely above schema doesn't work, because it's tedious to write same logic 100 times with just different table names. (I'm using Linq2SQL)
Currently my solution is:
Make a view that's based in all such tables and in application I just call a function that construction dropdownlist from that single view. But it's still tedious to change view definition everytime I add a new table.
Do you guys think of a better solution for this tedious work, possibly using reflection or some other tecnologies.
It is not a problem "Definitely above schema doesn't work, because it's tedious to write same logic 100 times with just different table names."
If I were you, I will mark an addition interface on these class using "partial class" feature.
Then, I will write few extension method for the partial class.
If anyone interested in the solution:
I've used reflection to solve this problem.
I use reflection over DataContext to get the Table (by string name), and get its fields and construct the optionlist.

What is the best way to print columns from different tables on the same row using the Axapta reporting tool?

It seems like each body section in an axapta report can only print columns from a single table(consistantly). For instance:
I have a report that has the following tables: SalesLine, InventTable and CustTable. Then I would like to print columns from each of this tables on the same row. It seems like I can do this when placing the fields in programmable sections but not when I place them in body sections.
I have found a few workaround that are either ugly or non-performant. There has to be a nice clean way to do this?
It should be possible to do this, there are several reports in the base system that work this way. Look at the SalesContractShipment report in 4.0 as an example.
On your report, create a datasource for SalesLine, and under that create datasource each for InventTable and CustTable. On InventTable and CustTable, make sure the FetchMode is set to 1:1. If you create a custom fetch method, make sure you call send() in the correct order. You should send CustTable first, then InventTable, then SalesLine last. On the report design, create a single body for SalesLine. You should then be able to use fields from any of the three tables in that body.
If you are still having trouble, I can think of two work arounds. One is to create a view based on those three tables, and create a report based on that view. The other is to create the report based on SalesLine and use displayMethods to lookup any fields you need from InventTable or CustTable.
You should be able to add multiple data sources to a report then create one body for the first data source that you added. Right-click the body and select New Control -> Field From AnyTableThatIsADataSource. You can then add any field that you want and it will print columns for all of those fields.
Put all the fields in the last SourceTable_Body and it'll show all the fields, because the QueryRun table by table and fill the body with each corresponding Body, so the last body will have all fields' data.
Consider using temporary tables. Fill it with your data first, than use in the report.

Resources