Was my offering helpful?  

On Monday, August 17, 2015 at 7:31:05 PM UTC-4, Elizabeth McGurty wrote:
>
> Oh!
>
> 1. You could just have a 'Participant' table, containing students, 
> professors, teachers, evaluators as distinguished by a role, is_active, 
> etc..
> 2. You could just have a 'Evaluation_Detail' table, containing at a row 
> level student_id, class_id, teacher_id, professor_id, evaluator_id for each 
> question, its response, then its evaluation as a comment and/or look-up 
> value from a grading table, etc..
>
> Queries would obviously be more 'where' intensive, but your associations 
> wouldn't be as deep.
>
> Liz
>
>
>
>
>
>
>
>
> On Monday, August 17, 2015 at 10:52:40 AM UTC-4, Scott Goci wrote:
>>
>> Hey Liz,
>>
>> Thanks for responding. Here's some initial responses:
>>
>>
>>    1. While I understand the need in an actual application for things 
>>    like a *Classroom* model (owned by a *Professor*), and then something 
>>    like a  *StudentClassroom* model (setting up *Students* to a 
>>    *Classroom*) to better help organize the data, what I'm looking for 
>>    really is how associations fit together when deeply nested outside of the 
>>    context of the actual application. I set up this example simply as a way 
>> of 
>>    exploring some of the problems it poses.
>>       - Ditto for a *School* model -- we can assume that a *School *has_many 
>>       :professors, etc.
>>    2. The idea is that as we get deeper into our models, it becomes 
>>    harder and harder to get back to the beginning. 
>>       - In my example, From an *Evaluation*, we would need 5 hops to get 
>>       back a *School* model for example (imagine 
>>       evaluation.response.question.exam.professor.school) 
>>       - Similarly, from the reverse side, it would be hard to query for 
>>       all *Evaluations* for a *School:*
>>          - *@school = School.first*
>>          - *@all_professors = @school.professors*
>>          - *@all_exams = Exam.where(professor_id: 
>>          @all_professors.pluck(:id))*
>>          - *@all_exam_questions = Question.where(exam_id: 
>>          @all_exams.pluck(:id))*
>>          - *@all_exam_responses = Response.where(question_id: 
>>          @all_exam_questions.pluck(:id))*
>>          - *@all_exam_evaluations = Evaluation.where(response_id: 
>>          @all_exam_responses.pluck(:id))*
>>       - While the above works, it took 6 lines to get there! Not to 
>>       mention the expense of doing a crazy amount of lookups
>>    3. So instead, what's the solution?
>>       - We could write an "all_evaluations" method in what would be our 
>>       *School* model using the above code
>>          - Solves the multiple lines problem, but not the query 
>>          complexity problem
>>       - Perhaps using delegate? Little more elegant than perhaps a 
>>       method, but again the complexity problem
>>       - Adding an extra foreign key to a model somewhere and 
>>       denormalizing the database a bit
>>          - Eg for *Evaluation*, maybe add exam_id to the class
>>             - To get back to a *School* now, it's 2 less hops (
>>             evaluation.exam.professor.school)
>>             - To get all *Evaluations* for a *School*, we can now do the 
>>             following, which is two less lines of code (and less joins):
>>                - *@school = School.first*
>>                - *@all_professors = @school.professors*
>>                - *@all_exams = Exam.where(professor_id: 
>>                @all_professors.pluck(:id))*
>>                - *@all_exam_evaluations = Evaluation.where(exam_id: 
>>                @all_exams.pluck(:id))*
>>             - This feels arbitrary though
>>             - if we are going to do this, why not just add a school_id 
>>             to an evaluation? 
>>             - Or a bunch of other foreign keys to all the tables to make 
>>             all hops 1-2 at most
>>          
>> In the end, I'm mostly trying to understand which strategy to use under 
>> which scenarios -- I see a lot of blog posts talking about the law of 
>> demeter and simplifying your associations (usually using delegate), but 
>> most of them have pretty simple connections like 
>> business.location.city_name, nothing as complex as chaining through 4-5 
>> associations to get back to the original object. It also feels dangerous to 
>> chain that much -- if at any point in the 
>> evaluation.response.question.exam.professor.school the associated object 
>> ends up being deleted somehow, then you break your ability to get back to 
>> the original object.
>>
>> Hope that helps explain my question more.
>>
>>
>> On Monday, August 17, 2015 at 8:45:51 AM UTC-4, Elizabeth McGurty wrote:
>>>
>>> Before I respond, I think that it would be helpful if you provided your 
>>> database entity–relationship model.  Also, I don't see that you have a 
>>> Classes, the school variety, table.
>>> Liz
>>>
>>> On Monday, August 17, 2015 at 1:18:38 AM UTC-4, Scott Goci wrote:
>>>>
>>>> I've been wrestling with database normalization and the "Rails Way" and 
>>>> I wanted to get peoples opinions as to if there's a best practices guide 
>>>> to 
>>>> how to do it. Here's some background:
>>>>
>>>> Let's assume we have a model/schema similar to the following:
>>>>
>>>> class Student < ActiveRecord::Base
>>>>    has_many :student_exams
>>>>    has_many :exams, through: :student exams
>>>> end
>>>>
>>>> class StudentExam < ActiveRecord::Base
>>>>   belongs_to :student
>>>>   belongs_to :exam
>>>> end
>>>>
>>>> class Exam < ActiveRecord::Base
>>>>   has_many :questions
>>>>   belongs_to :professor
>>>>   has_one :college, through: :professor
>>>> end
>>>>
>>>> class Question < ActiveRecord::Base
>>>>   belongs_to :exam
>>>>   has_many :responses
>>>>   
>>>>   # question_text: text
>>>> end
>>>>
>>>> class Response < ActiveRecord::Base
>>>>   belongs_to :question
>>>>   belongs_to :student
>>>>
>>>>   # response_text: text
>>>> end
>>>>
>>>> class Evaluation
>>>>   belongs_to :response
>>>>   belongs_to :professor
>>>>
>>>>   # grade: integer
>>>> end
>>>>
>>>>
>>>> The idea is that a *Professor* creates an *Exam* and* Questions*, and 
>>>> then assigns students through *StudentExam* to take that exam. The 
>>>> students then generate *Responses* to the exam questions, and then 
>>>> those *Responses* are graded by *Evaluations* done by the *Professor*.
>>>> Now, given the above background, I wanted to ask a few questions to get 
>>>> peoples opinions on how to structure this app:
>>>>
>>>> *Questions*
>>>>
>>>>    1. In general, are there any changes you guys would make with the 
>>>>    given associations?
>>>>    2. For the *Response* model, does it make sense to do "belongs_to 
>>>>    :student", or should it instead be "belongs_to :student_exam"? It 
>>>>    feels more logical to have the former, because we can get the exam 
>>>> through 
>>>>    the question if need be (response.question.exam), and its really a 
>>>>    student responding to it, not a student_exam. But if we used 
>>>> student_exam, 
>>>>    we could use response.student_exam.exam to get back to the exam, 
>>>>    and response.student_exam.student to get back to the student.
>>>>    3. If we were on an *Evaluation* and we wanted to back to a exam, 
>>>>    it would seem quite cumbersome to do 
>>>>    evaluation.response.question.exam just to get back to the exam. 
>>>>       - Now we could always create a method on the model that just 
>>>>       shortened it for us, but *is there a point when you are chaining 
>>>>       associations that somewhere along the line you add in another 
>>>> foreign_key 
>>>>       to a table for easy lookup*?
>>>>    4. If we wanted to see all *Evaluations* for an *Exam*, what would 
>>>>    be the best way to do that? 
>>>>       - Only way I could see to do it easily would be to break it up, 
>>>>       something like:
>>>>          - @questions = @exam.questions
>>>>          - @responses = Response.where(question_id: 
>>>>          @questions.pluck(:id)
>>>>          - @evaluations = Evaluation.where(response_id: 
>>>>          @responses.pluck(:id) 
>>>>       - This seems kind of painful
>>>>    
>>>>
>>>> Let me know your thoughts -- or if you have any great books on the best 
>>>> strategies for normalizing/denormalizing within or without the scope of a 
>>>> rails app, I'd love to hear them.
>>>>
>>>>
>>>>
>>>>

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rubyonrails-talk/19ea8bf0-2d8a-4363-b74f-1519f4d80b5b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to