1

Many thanks for your help on this.

For the first example entry must have qualification 2 in sector 5.

Requirement can be anything (single, or multiple qualifications using AND, OR logical operators)

1 What is the nature of the relation between Notice and Requirement ?

  • A Notice has one or more requirements, like in these four examples.

2 Between Tender and Requirement

  • Tender has one or many Requirements.

3 Between Tender and Notice ?

  • I have already told you that Tender, Notice are the same thing.
  • Name it Entry or Example or whatever you want.

I just want to store these raw numbers, forget about class, names... You have 4 examples, which are raw numbers, you don't need anything else, because there is nothing else.


Example 1

  • Sector/Qualification 5.2

Example 2

  • Sector/Qualifications 3.9 and 4.10

Example 3

  • Sector/Qualifications 6.1 or 6.3

Example 4

  • Sector/Qualifications (3.1 and 3.2) or (5.6 and 7.1)

Example 5

  • Sector/Qualifications (3.1 or 3.2) and (5.6 or 7.1)

Example 6

  • Sector/Qualifications (6.4 or (3.7 and 1.1)) and (9.6 or 8.5)

class Example < ActiveRecord::Base
  has_many :requirements
end

class Requirement < ActiveRecord::Base
  belongs_to :example
end

  create_table "examples", :force => true do |t|
    t.integer "example_number"
  end

  create_table "requirements", :force => true do |t|
    t.integer "example_id"
    t.integer "sector_number"
    t.integer "qualification_number"
  end
user455387
  • 49
  • 4

3 Answers3

5

The problem you are experiencing is, trying to force-fit your OO classes into a Relational database.

If you want the power and flexibility of a Relational databases; if you wish to avoid "re-factoring" the data every time you "re-factor" your classes, do not do that.

Forget about your classes, and model the data as data. It will not be "complex" or "tricky". When you are finished, map your classes to the data.

If you want more information on the absurdity of implementing OO classes in the database, read this answer starting from the 11 Dec 10 entry.

Now if you tell us what your data is, and how it is related to each other, we can model that for you.

Responses to Comments 27 Dec 10

Sure thing. Forget the tables and classes for now, just think about the data, in terms of Entities or Things, Nouns, that may relate to each other. Do not worry about the AND/OR, that is easy once the data is modelled correctly (and impossible if not !).

1) Does the Class identify the Qualification; Sector ? And that is independent of Enterprise ? (I think so, so I have modelled that.)
2) Do you have names instead of numbers for MinimumClass/Sector/Qualification ? (Please stop sticking Id columns on everything that moves: it seriously hinders the modelling process; understanding the data.) I need examples of real data: Sector; Qualification; Class.
3) Does each of Class, Sector, Qualification exist on its own; eg. Qualification exists only in the context of Sector ?

Have a look at this initial ER Diagram (Page 1) (we are not ready for the Data Model.) (inline links do not work on some browsers/versions.)

  • You have a good idea of what you want; I am asking you to set that aside and think about just the data and how it relates to other data
  • I suspect the model on the left is what you have been staring at; it is familiar; but there is too much going on in one place. It is definitely not Normalised, and that is what we have to fix first.
  • I think you cannot have a Qualification without a Sector. Right ?
  • next, a Qualification exists independent of Class
  • next, a Class has a set of Requirements, which consists of Qualifications. Right ?
  • then we can think about what a Class is; what those Requirements are; the ANDs and ORs.

1) The link provides Sector-Qualification numbers, sure, but that looks more like chapter-section numbers that will change next year. I accept that people do talk about a "Classe Une qualification"; but I doubt the people actually discuss a "1.3 qualification". I have modelled it based on what you stated, but if the Sector/Qualification numbers are not stable, you are better of either using increment of 10; or some other number or code that means something to you and not the outside world, The Name is the meaning that will not change.

2) AND/OR. I have used two methods in the past that are useful here. One was based on a series of BIT or BOOLEAN Indicators, such as IsOne and IsOneOfTwo; that was more useful for the coding involved; and there were IsMandatory requirements involved.

For you, a simpler method using a Weight column is all you need. The total Weight of any qualifying set for a Class, in the same Sector* (not the total Weight for a Class, they may be several sets) equals 1.0. If the Weight of a row for a Class, in the same Sector, is less than 1, you need to keep ANDing it with other rows, to make a full Class. This will allow you to have threes in future. I have provided the full set of rows for the examples you used. Ask specific questions if any of that is not completely understood.

Data Model

Evaluate this Initial Data Model (Page 2) (inline links do not work on some browsers/versions.)

Readers who are not familiar with the Relational Modelling Standard may find the IDEF1X Notation useful.

Response to Comments 01 Jan 11

3) If I have (3.1 and 3.2) or (5.6 and 5.9) if I use 0.5, how can I differentiate this with (3.1 and 3.2 and 5.6 and 5.9), I must use a different weight for each group that's right ? 0.5 for the (3.1 and 3.2), and 0.6 for (5.6 and 5.9) ?

No. You've added a bit to the question (no problem; modelling is a back-and-forth exercise). Never play with trying to identify control in the data. The control lies in the Keys, the Identifiers. That differentiation is already provided in the Model. The changed requirement (question, not table) is now:

  • For a Class to Qualify, the weight of the Requirement must be at least 1.0 in the same Sector

(5.6 and 5.9) remain at 0.5 each; they are a different Sector (5) to (3.1 and 3.2) which are (3).

4) Have you read and understood the IDEF1X Notation, and do you appreciate the compound keys in the model ? Requirement PK is (ClassNo, SectorNo, QaulificationNo); the only data is Weight.

5) Are you clear about the Business Rules that the Model supports ? Would you like me to list them ?

Responses to Comments 02 Jan 11

Some precision, (1) Class is completely different from Sector/Qualification, they are not connected directly.

Yes, it already is independent. Class is as per all statements above, plus Sector and Qualification being correct: "SECTORS; ACTIVITY OF QUALIFICATION AND CLASSIFICATION OF THE COMPANIES ENGAGING IN THE BUILDING SECTOR". We have to take one step back, and confirm the simple rules before moving forward. New Data Model. Please confirm/deny each of these statements, working side-by-side with the DM:

  • A Sector is made up of 1-to-many Qualifications (the link provided)

  • A Qualification is a requirement in 1-to-many Classifications

  • A Classification requires 1-to-many Qualifications:

    • a set of Qualifications is required to make a Qualification
    • Some Qualifications are OR-ed
    • Some Qualifications are AND-ed
    • the set of Qualifications required for a Classification, that are OR-ed or AND-ed, must be in the same Sector
  • (New info) A Classification Notice is issued to 1-to-many Enterprises.

  • An Enterprise is endorsed with 1-to-many Classifications.

(2) You assume that the two operands have the same Sector, it can be (3.1 and 4.6) or (5.6 and 1.9).

(I am assuming nothing, I am distilling the info provided by you: give me more info, and I will give you a more precise model) ;-}

No problem. (2.a) Identify the basis for (3.1 and 4.6) being grouped. (2.b) Identify the name of each Classification (3.1 and 4.6), (5.6 and 1.9); what makes them different/distinct from the group (3.1 and 3.2)

(4) for the ERD and dm we just need to change Enterprise to Notice and connect it to Requirement.

Don't worry about the "connections", that is the job I have accepted, at your request. ;-}

(5) each Notice has many Requirements that each enterprise must meet to be allowed to participate.

(5.a) What is the content of these Notices; is it not an endorsement that they have achieved a Classification ? Or that they have achieved a single Requirement ?

(5.b) Does the system have to track each requirement that each Enterprise meets ?

(5.c) Separate to requirements, when an Enterprise achieves a Classification (set of Requirements) does the system issue a Notice of Classification ?

Update

Based on the new information, I can see where you are heading. Please evaluate this Very Tentative Data Model (Page 3).

  • The OR-ing and AND-ing is even simpler
  • Each Classification has a set of possible Requirements (OR-ed)
  • Each ClassificationSet is required in full (AND-ed)
  • Weight is no longer required
  • This tracks each Qualification awarded to an Enterprise (user inserts this); and updates IsNotified when the Notice is issued
  • and each Classification achieved

Perhaps daily, a procedure is required to process the EnterpriseQualifications (compare against a ClassificationSet) and produce (insert) EnterpriseClassifications. And again update IsNotified when the Notice is issued.

Ok, I have removed the bits you don't need, as per comments, and updated the Tentative Data Model.

Awaiting response re the remaining questions. So now it is an Incomplete Data Model (Page 4).

In order to "connect" Notice to Requirements, I need to know the basis of the relation; it cannot be one Notice to many, any Requirement.

Simplicity. Actually, I am a master of simplicity. K.I.S.S. isn't a shallow mantra, there is actually a science to it. In order to eliminate problems during development and coding, you need a clean data model; simple, uncomplicated. That's what I am trying to give you. But I need information.

Awaiting response re the remaining questions. So now it is an Confused Data Model (Page 5).

Response to Comments of 05 Jan 11

Ok, we are getting somewhere. I have revised the DM based on your latest revision of the question. We now have the Fifth Data Model (Page 6) (not a problem, that is the nature of modelling, paper is cheap; re-factoring is expensive).

  • The initially identified, Class, etc, are removed. Notice is Tender.

  • Names, identification, definition, are actually very important, you will realise that once you start coding; and later when you need to expand the Data Model.

  • The Weight that was based on the earlier understanding, is also removed. We now have the notion of optional sets of Requirements per Tender (the OR), and each set is mandatory (the AND).

  • the code, and the class definitions, will now be dead simple.

  • I have used the exact data values provided in your latest examples.

  • Blue denotes static Reference tables; Green denotes Identifying elements.

  • Please ensure that you read the IDEF1X Notation document, so that you can fully interpret the DM, and produce DDL. That will have the full integrity, strength and power (flexibility) of the Relational Model.

When this is complete, I will clean up my answer, delete all the obsolete information that we worked through.

Response to Comments of 07 Jan 11

(1) The examples 2 and 3 are stored in the same way, how do you distinguish (3) OR from (2) AND ?

Data specification error on my side. Fifth Data Model (Page 7) unchanged, with corrected data.

(2) Does it supports any combination of OR/AND requirements ? These are just examples it can be anything, like (6.4 or (3.7 and 1.1)) and (9.6 or 8.5). It must be flexible.

The Data Model has all the "flexibility" that you had previously identified. No, it does not support any requirement that you have not identified (I have a fair amount of capability but ESP is something I do not have!).

In that case, evidently, you do not "know exactly what you want to do", you are introducing new requirements, again. And the data is not raw, it is very specific control data, so please, let's stop treating this as a simple requirement to "store raw data", and get on with the not-so-simple job.

What other "flexibility", "exactly", do you require ? Specify all those forms, and I will give you a Data Model that satisfies all the requirements; that will take less time and effort than this incremental back-and-forth method you are using.

  • In case you have forgotten, here is an Early version of your Question. All the revisions of your question are available for anyone with enough points to see.

  • The incremental method is no doubt good for you, to understand your data, and to understand the progression of the model, but as you can see it is a very slow and time-consuming road. Fine when you are working alone and have all the time in the world; not fine when you are working with a professional.

  • The fast road is to identify all your requirements up front, and let the professional deliver a complete data model. (Eg. your latest new requirement will take me five minutes; but I could have included that in the last Data Model if you had identified it; and of course that would not be complete either.) Then ask questions to fill in any gaps of understanding.

  • An experience professional Data Modeller does not need to work in tiny incremental steps. We look at the whole picture (we do want a Relational Database that has no duplication) and normalise the entire model. Once.

  • And do not waste time defining your objects and classes either, they will keep changing with every tiny increment; you can wait until the Data Model is complete, and define your classes, once. That will be stable.

I have updated the document to show the series of revisions that have been produced for the Question as a result of your demands for small incremental progress.

I have annotated Page 7 with the above, but the Fifth Data Model remains unchanged.

Please make all amendments (specify all the "exact" "flexibility" you require) to your question, and I will answer it. Please do not change the text of your Question or delete anything; leave what is there alone, and add to it.

Response to Comments of 08 Jan 11

(1) I added two more examples, I'll be pleased to see your generic method, I want it. Anyway with these two examples I think it's enough for most cases.

Those new examples introduce (implicitly) yet more new requirements, that of:

  • basically a tree structure (unless you want massive duplication and the consequent data integrity problem).

  • AND and OR occurring at any point/node in the tree

    • That is supplied by a Boolean IsAndSet; false means it is an OR set.
      .
  • a RequirementSet can be made up of:

    • Qualifications;
    • other RequirementSets (unless you want massive duplication);
    • or both

    • That requires a Subtype (explained in the IDEF1X Notation document) to allow for the optional columns, the Foreign Key. There is only one, therefore no Discriminator is required. It is an Exclusive Supertype/Subtype.

    • It remains optional, only for a RequirementSet that is made up of other RequirementSets

  • The Nodes are Atomic or Leaf Level, anything else is not (it is made up of Nodes). The Nodes eliminate duplicate data and Update Anomalies.

Some developers would collapse the RequirementSet and RequirementSetNode into one table: that will be de-normalised and difficult to maintain. Further, it would require Null Foreign Keys. Each of those separately break Relational Modelling and design rules, and have consequential problems, so I do not provide that, I provide only Standard-compliant models. It may look like it is harder to code for but actually it is easier.

I have provided all the data to supply your examples (5) and (6), as well as a tree diagram. You can refactor the data supplied for examples (1) to (4) [if you had given these examples at the outset, the five previous versions of the Data Model would not have been required, and the data I supplied for them would not need refactoring].

Updated the Data Model, we are now on at Sixth Data Model (Page 8)

Next example ... ?

Response to Comments of 10 Jan 11

(1) I don't see why it can't store any combination.

It can, AFAIK ... but there is always the possibility that someone in New Caledonia comes up with something it can't store; being conservative, I do not declare that it can store any combination; just that it is generic and extremely flexible, while maintaining full Relational integrity and power.

(2) Can you please explain what do you mean by "The Nodes are Atomic or Leaf Level" ? You mean that it doesn't include the head of the tree ?

Those terms are common in B-Tree and Directory structures.

I have changed RequirementSetNode to RequirementSetChild to improve understanding.

  • Leaf level is the very end of any branch. Note that the Leaves are not all at the same Level. In our case, they are always Requirements.

  • A Node is any branch or joint in the tree, in the tree diagram (not the model); a collection of either Nodes or Leaves or a combination. In our case, they are RequirementSets.

    • The collection of Leaves belonging to a RequirementSet is in Requirement
    • The collection of Nodes belonging to a RequirementSet is in RequirementSetChild.
      .
  • Atomic is a Transaction (IEC/ISO/ANSI SQL Database) term, from the ACID Properties. Atomic means it is indivisible; either the whole unit is valid; or it is invalid. What I am stating here is, from your app point of view, you just need to treat each Node (the items it contains) together, as one unit.

  • (The Leaf is always Atomic.)

The exact data examples should clarify; I have provided an expansion on page 9.

(3) "It remains optional, only for a RequirementSet that is made up of other RequirementSets" What does remain optional ?

RequirementSetChild is an optional child of RequirementSet. Not every RequirementSet has RequirementSetChildren; only the RequirementSet that are Nodes, hence it is optional. (But of course, the child always has a parent; that is a Foreign Key, and not optional.)

(4) "It is an Exclusive Supertype/Subtype." What is the Supertype and Subtype in your model? What does Exclusive mean in this case, a Subtype can't have Subtypes?

Actually, since there is only one Subtype, we can remove the whole Supertype::Subtype issue, and treat it as a simple optional child. Model Changed.

halfer
  • 19,824
  • 17
  • 99
  • 186
PerformanceDBA
  • 32,198
  • 10
  • 64
  • 90
  • @user455387. Answered in my post. There is still a bit of back-and-forth to go through. – PerformanceDBA Dec 26 '10 at 15:19
  • Class doesn't have a name, it's just a number, it is peer Domain, and independent of Enterprise, Sector, and Qualification. MinimumClass and Class are the same. Sector/Qualification each have a specific number and a name. i have provided three real examples, generally only numbers are provided but sometimes the names too. here is the data for "Batiment" domain, www.mhu.gov.ma/NR/rdonlyres/0F2ED714-2DBA-4090-BFD2-2ABEE2F330C0/0/listsecteurqualif.pdf – user455387 Dec 27 '10 at 09:01
  • @user455387. Answered in my post. Now I need feedback or the ERD as well as the DM. – PerformanceDBA Dec 27 '10 at 12:49
  • Thank you very much, if I have (3.1 and 3.2) or (5.6 and 5.9) if I use 0.5, how can I differentiate this with (3.1 and 3.2 and 5.6 and 5.9), I must use a different weight for each groupe that's right ? 0.5 for the (3.1 and 3.2), and 0.6 for (5.6 and 5.9) ? – user455387 Jan 01 '11 at 03:19
  • @user455387. My pleasure. Answered in my post. I need feedback, questions on the DM, so that you fully understand it; that it captures your requirement. – PerformanceDBA Jan 01 '11 at 13:14
  • Some precisions, (1) Class is completely different from Sector/Qualification, they are not connected directly. (2) You assume that the two operands have the same Sector, it can be (3.1 and 4.6) or (5.6 and 1.9). (4) for the ERD and dm we just need to change Entreprise to Notice and connect it to Requirement. each Notice has many Requirements that each entreprise must meet to be allowed to participate. – user455387 Jan 01 '11 at 15:18
  • @user455387. Answered in my post. If the comments are restrictive, you can add amendments to your question. – PerformanceDBA Jan 01 '11 at 22:28
  • "The set of Qualifications required for a Classification." (1) Classification is completely different and independent from Qualification, it represents the size of an entreprise, small, medium, big... (2) qualification is a kind of certificat that prove that an entreprise can do the job. it's provided by the government. – user455387 Jan 01 '11 at 23:40
  • @user455387. Ok. But previously you were identifying that the Requirements were grouped (sets; AND-ed; OR-ed) ... how do we identify those sets, what shall we call them ? Let's call the size "Size", to keep them separate, at least until we resolve this. Does Classification have anything to do with "minimal class 1 ... 2" ? Produced a new tentative DM. You are picking and choosing your responses; I need you to please respond to all questions. Then I will respond. – PerformanceDBA Jan 01 '11 at 23:57
  • (5.b) Does the system have to track each requirement that each Enterprise meets ? NO, It must store the requirement for each Call For Tender. – user455387 Jan 02 '11 at 04:26
  • Keep it simple, I just need to store the requirements. – user455387 Jan 02 '11 at 04:28
  • (1) Class is just another term for Size. (2) Keep it simple, I just need to store the requirements. I have a call for tender, with requirements, no need to track anything else. (3) Get ride of Size, Entreprise, EntrepriseQualification, EntrepriseClassification, Classification, ClassificationSet. (4) Create Notice and connect it with Requirement. (5) a Notice can have one or many Requirement. (6) Sector, Qualification, Requirement are OK. (7) you're using SetNo to identifie each groupe ? (8) Classification is not a set of Requirements. – user455387 Jan 02 '11 at 05:01
  • @user455387. (7) Yes, green text is actual data (3) Done. But you need to identify what the object is, that replaces Classification & Set, they cannot be removed yet; they hold the structure for everything you have identified since the beginning. Where would you do the AND-ing and OR-ing ? Is it Notice ? well, define it then, what is a "Notice". (5.b) So where is "Tender" ? it can't be merely any set of Requirements, there must be some constraints. – PerformanceDBA Jan 02 '11 at 08:00
  • (1) You're confusing Class with Qualification, So forget about Class, (2) I just need to store raw qualification numbers in the database. – user455387 Jan 05 '11 at 04:22
  • 1
    @user455387. What, the red did not go to green yet ? Just write more code, very small steps. Refactor both the code, and the data every week or so. It is not possible for me to be confused: it is your question, your requirement; I cannot model what you cannot define. I updated the data model with all the info you provided, days ago; Notice is now connected to Requirement. Waiting for your answers (check my answer). I changed the title today, reflecting your comments. – PerformanceDBA Jan 05 '11 at 14:38
  • Sorry I know exactly what I want to do, you don't need to know everything to do it, please have you read the code that I have provided ? Example and Requirement ? I have provided 4 examples, now we need to store them that's all. Why you keep asking me about Tender, Notice, Class ? Name it what you want it will not change anything, My problem is to store these raw number. – user455387 Jan 05 '11 at 16:09
  • 1
    @user455387. Sorry for the delay, I was away. (I ask you questions onl due to your statements; when you introduced Tender; Notice; I had to understand what they were; how they related to what we had already modelled). The idea is to store the"raw" numbers in a way the doesn't need re-factoring every Friday, right ? I have updated the answer and teh model to reflect the latest information provided. – PerformanceDBA Jan 06 '11 at 23:02
  • Now I have two questions. (1) The examples 2 and 3 are stored in the same way, how do you distinguish (3) OR from (2) AND ? (2) Does it supports any combination of OR/AND requirements ? These are just examples it can be anything, like (6.4 or (3.7 and 1.1)) and (9.6 or 8.5). It must be flexible. Thanks you. – user455387 Jan 07 '11 at 09:51
  • Sorry i haven't changed anything to the requirements "Requirement can be anything (single, or multiple qualifications using AND, OR logical operators)" you can read it at the top, I just provided you with 4 examples. I have changed nothing, just I removed all the other things that keep us from dealing with the main problem. – user455387 Jan 08 '11 at 00:54
  • 1
    @user455387. Say it any way you like, the existing Data Model is complete for the previously specified question & examples. The new examples **identify** a new (not previously identified) requirement. I don't care, I can supply any requirement, **just tell me what it is**. Apology accepted, but it is not possible to supply a requirement to do "anything". Now provide any more, or better examples, **all of them**. Updated the DM. – PerformanceDBA Jan 08 '11 at 01:18
  • I see, of course it looks like "anything" but it's not, We have Two operator AND, OR and they can be grouped. I can't provide every possible combination. I don't choose what should be stored, that's why I need a generic way to store them, or I will have problems afterward... It's not easy, but it can be done. – user455387 Jan 08 '11 at 01:38
  • 1
    @user455387. "It" can be done, if, and only if, "it" is identified. "It" **is** easy for me. What is unidentified cannot be done; cannot be promised. I can give you a "generic" method, that will have less limitations than a non-generic method ... but even that will have some form of limitation, it will not do "anything" that is unidentified. – PerformanceDBA Jan 08 '11 at 01:45
  • (1) I added two more examples, I'll be pleased to see your generic method, I want it. (2) A compiler can store any combination in memory, not of just two operators... it parses expressions and map them to structures, I'll examine how it's done. Anyway with these two examples I think it's enough for most cases. Thanks. – user455387 Jan 08 '11 at 02:00
  • Sorry for my bad english, I'm not trying to prove anything to you, I'm learning, I do my best to express myself clearly :-) Merci beaucoup pour votre aide. – user455387 Jan 08 '11 at 02:25
  • 1
    @user455387. Mon ami, the day you can **define** exactly what you want, you will open the door to having it. Data Model updated (page 8). Vous êtes le plus bienvenu. Sorry for my bad French. – PerformanceDBA Jan 08 '11 at 05:35
  • Where is the Updated the Data Model ? Thanks – user455387 Jan 08 '11 at 16:27
  • @user455387. Since I amalgamated all the separate revisions into one doc, and all the "xxxx Data Model" links now point to the same doc, different pages, I did not add yet another link. Clarified each of the links, and added a new one in the latest post. Added page nos to the doc. – PerformanceDBA Jan 09 '11 at 02:19
  • Thank you, (1) I don't see why it can't store any combination. (2) Can you please explain what do you mean by "The Nodes are Atomic or Leaf Level" ? You mean that it doesn't include the head of the tree ? (3) "It remains optional, only for a RequirementSet that is made up of other RequirementSets" What does remain optional ? (4) "It is an Exclusive Supertype/Subtype." What is the Supertype and Subtype in your model ? What does Exclusive means in this case, a Subtype can't have Subtypes ? thanks. – user455387 Jan 10 '11 at 01:07
  • @user455387. Answered in the post. – PerformanceDBA Jan 10 '11 at 21:33
  • 1
    @user455387. Mon ami. If you have no further questions, could you please vote, choose an answer; and I will clean up/strip my answer for the record. – PerformanceDBA Jan 14 '11 at 13:43
1

If you follow the 'test-driven' approach, you should start with some tests and write code to make them pass. So your most basic example, could start out as the following in RSpec. From what you've said you have a 'tender' and an 'enterprise' - I'd start there.

describe 'inviting an enterprise to tender' do

  describe 'for a tender that has a minimum class' do

    before do
       @tender = Tender.create(:minimum_class_level=>4)
    end

    it 'should invite the enterprise to tender if the enterprise has class level 4' do
       enterprise = Enterprise.create(:class_level=>4)
       enterprise.should be_invited_to_tender(@tender)
    end

    it 'should not invite the enterprise to tender if the enterprise has class level 3' do
       enterprise = Enterprise.create(:class_level=>3)
       enterprise.should_not be_invited_to_tender(@tender)
    end

end

Write some code to make that pass, and once that's green, move on to adding further models as and when required. Your data model will emerge, as will your code 'documentation' in the form of a test suite.

stef
  • 14,172
  • 2
  • 48
  • 70
0

What you're building sounds terribly complex. But if you want to continue, you might want to look at has_many :something, :through => :something_else: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many

iain
  • 16,204
  • 4
  • 37
  • 41