-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix validation for achievement conditions #693
Fix validation for achievement conditions #693
Conversation
minhtule
commented
Dec 17, 2015
- Fix the query to retrieve achievement conditions of a particular conditional object
- Improve the naming
- Remove complicated trait in achievement condition factory
@allenwq does this reflect correctly the behavior of the function? |
c277052
to
cf5c0fc
Compare
@MinhTu Yep, think it can be generalised. And can we have a spec for it ? to test that it works for any conditionals. |
assessment = create(:assessment, course: course, id: Time.now.to_i) | ||
achievement = create(:achievement, course: course, id: Time.now.to_i) | ||
required_achievement = create(:achievement, course: course) | ||
existing_achievement_condition = create(:achievement_condition, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Useless assignment to variable - existing_achievement_condition
.
da10287
to
b0fdd28
Compare
I'm not entirely sure what's being fixed? |
# | ||
# @param [Course::Achievement] achievement The achievement to return achievement conditions for. | ||
# @param [Object] conditional The object that is declared as acts_as_conditional and for which |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should specify the module that all such classes implement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
acts_as_conditional
is defined under
module Extensions::Conditional::ActiveRecord::Base
module ClassMethods
# Functions from conditional-and-condition framework.
# Declare this function in the conditional model that requires conditions.
def acts_as_conditional
...
end
end
end
Any class subclassing ActiveRecord::Base
can add acts_as_conditional
. What module should I specify? ActiveRecord::Base
? And how should I specify it in the documentation part?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extensions::Conditiona...ConditionalInstanceMethods OR use duck typing. What are the methods each of these classes need to implement, and declare those methods. See the yard documentation.
The main fix is in the SQL query. |
@@ -37,7 +38,9 @@ def achievement_conditions(achievement) | |||
(SELECT cca.achievement_id | |||
FROM course_condition_achievements cca INNER JOIN course_conditions cc | |||
ON cc.actable_type = 'Course::Condition::Achievement' AND cc.actable_id = cca.id | |||
WHERE cc.conditional_id = #{achievement.id}) ids | |||
WHERE cc.conditional_id = #{conditional.id} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put this in a SQL heredoc block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@minhtule do you know what heredoc is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. If you use <<-SQL RubyMine will syntax highlight SQL.
333de76
to
6184178
Compare
fd1ad1f
to
fb6491c
Compare
@lowjoel please review! |
end | ||
end | ||
|
||
context 'when an achievement is required by another conditional with the same id' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@minhtule I stared at this for a while, I think finally get what you're trying to do.
Achievement conditions store a reference to their conditional, and the conditional is a polymorphic relation. So you want to make sure that two different polymorphic types with the same ID can exist. Is that what you're testing?
If that's what you're testing, what you should do is make the conditional_type and conditional_id columns a unique index, then this scenario doesn't really need to be tested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making (conditional_type, conditional_id) a unique index in the general condition table means the conditional appears only once in the table, which mean a conditional can only have 1 condition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, then (conditional_type, conditional_id, condition_type, condition_id) as the unique key? Is that what you're trying to do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, hang on, is there a general condition table? I remember only specific conditional condition tables?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, course_conditions -- it's an actable table, so the unique key should be (actable_id, actable_type, conditional_id, conditional_type). Does that make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we have a general condition table and it has 2 polymorphic relations: conditionals and specific conditions. Sure, it's definitely a better solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I just recall that this test is to catch the mistake in the SQL query fixed in this PR here. Please see the comment over there.
Adding the index will le us remove the validation of duplicated specific conditions though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I see the problem.
Mark this extra test as a TODO, removing when activerecord-hackery/squeel#390 is fixed, just like the SQL query. Typically you'd be using squeel and not writing raw SQL. Do the same for the other PR that does something like this.
5aa4544
to
08eee73
Compare
(SELECT cca.achievement_id | ||
FROM course_condition_achievements cca INNER JOIN course_conditions cc | ||
ON cc.actable_type = 'Course::Condition::Achievement' AND cc.actable_id = cca.id | ||
WHERE cc.conditional_id = #{achievement.id}) ids |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lowjoel This query gives false validation when 2 different conditionals with the same id have the same condition e.g. when achievement 2 requires achievement 1 and assessment 2 also requires achievement 1. This validation fails (while it's not supposed to). The test catches this error.
08eee73
to
29c7342
Compare
@lowjoel added TODO in the spec |
…gs-for-achievement-condition-validation Fix validation for achievement conditions