diff --git a/app/controllers/v1/reviews_controller.rb b/app/controllers/v1/reviews_controller.rb index 391c3b9923760a274f3635f71408b0e73350f017..0eb054edebb38ace3fcbf954f52676b706eb35d3 100644 --- a/app/controllers/v1/reviews_controller.rb +++ b/app/controllers/v1/reviews_controller.rb @@ -4,7 +4,9 @@ class V1::ReviewsController < ApplicationController # GET /v1/collections/1/reviews def index - render json: reviewable.reviews + render json: ActiveModel::ArraySerializer.new( + reviewable.reviews, + each_serializer: ReviewSerializer) end # GET /v1/collections/1/reviews/1 @@ -16,12 +18,34 @@ class V1::ReviewsController < ApplicationController # POST /v1/learning_objects/1/reviews.json def create review = reviewable.reviews.new(review_params.merge(user: current_user)) + errors = process_creation review - if review.save + # If review has any errors, status 422 + if errors.any? + render json: errors, status: :unprocessable_entity + else render json: review, status: :created + end + end + + def process_creation(review) + # Store errors + errors = [] + + # If review saved, without errors ... + if review.save + # ... build ratings objects from parameters + review.review_ratings.each do |r| + r.review = review + # ... and store if + r.save + errors << r.errors + end else - render json: review.errors, status: :unprocessable_entity + errors << review.errors end + + errors = errors.map { |e| e.messages }.inject(:merge) end # DELETE /v1/learning_objects/1/reviews/2 @@ -56,7 +80,7 @@ class V1::ReviewsController < ApplicationController # Never trust parameters from the scary internet, only allow the white list through. def review_params - params.require(:review).permit(:name, :description, :pros, :cons) + params.require(:review).permit(:name, :description, :pros, :cons, review_ratings_attributes: [:rating_id, :value]) end def set_review diff --git a/app/models/review.rb b/app/models/review.rb index e14cc9bd8057afe760cadb269f1ffdce312c73e9..1bd935ac36f2ab3255e8ee1d2b708a1383fc7a0d 100644 --- a/app/models/review.rb +++ b/app/models/review.rb @@ -22,13 +22,14 @@ class Review < ActiveRecord::Base has_many :review_ratings has_many :ratings, through: :review_ratings has_many :rates - has_many :complaints, as: :complaintable - validates_presence_of :user, :reviewable + validates_presence_of :user, :reviewable, :review_ratings validates_inclusion_of :reviewable_type, in: %w(LearningObject Collection), message: 'Only LearningObjects and Collections are reviewable.' validates_uniqueness_of :user, scope: [:reviewable_id, :reviewable_type] + accepts_nested_attributes_for :review_ratings + default_scope { includes(:user) } def rating_values diff --git a/app/models/review_rating.rb b/app/models/review_rating.rb index 9cfb0c82f03db715880f6914b2578fcbbb5c7f4c..d356332f0e0033a65c59ccf6151924a984044a00 100644 --- a/app/models/review_rating.rb +++ b/app/models/review_rating.rb @@ -15,7 +15,7 @@ class ReviewRating < ActiveRecord::Base belongs_to :rating validates_inclusion_of :value, in: Array(1..5), message: "Review Rating must be between 1 and 5." - validates_presence_of :review, :rating + validates_presence_of :rating validates_uniqueness_of :rating, scope: :review def self.default_names diff --git a/app/serializers/review_rating_serializer.rb b/app/serializers/review_rating_serializer.rb new file mode 100644 index 0000000000000000000000000000000000000000..c1b78bb49f5e2c2bbe234f3b7f73b1aa96b50902 --- /dev/null +++ b/app/serializers/review_rating_serializer.rb @@ -0,0 +1,3 @@ +class ReviewRatingSerializer < ActiveModel::Serializer + attributes :review_id, :rating_id, :value +end diff --git a/app/serializers/review_serializer.rb b/app/serializers/review_serializer.rb index 2ab71575c5c732752b98e2e322e486e00a4d0c0f..8385d65f374aa3b3e9639c4b3299290de8e7ee5d 100644 --- a/app/serializers/review_serializer.rb +++ b/app/serializers/review_serializer.rb @@ -1,3 +1,3 @@ class ReviewSerializer < ActiveModel::Serializer - attributes :id, :name, :description, :pros, :cons, :rates_count, :created_at, :updated_at, :reviewable, :user + attributes :id, :name, :description, :pros, :cons, :review_ratings, :rates_count, :created_at, :updated_at, :reviewable, :user end diff --git a/test/controllers/v1/reviews_controller_test.rb b/test/controllers/v1/reviews_controller_test.rb index 6f2785711c303e47ada16666affdc8bbd069dce8..50514c7e662ad3d627b77be0d685ec3aa8f8288a 100644 --- a/test/controllers/v1/reviews_controller_test.rb +++ b/test/controllers/v1/reviews_controller_test.rb @@ -34,10 +34,15 @@ class V1::ReviewsControllerTest < ActionController::TestCase object_param_name = "#{object.class.to_s.downcase}_id".to_sym object_param_name = 'learning_object_id' if LearningObject == object.class post :create, review: { - name: 'Test of review', - description: 'testing', - pros: 'my pros', cons: 'my cons' + name: 'Test of review', + description: 'testing', + pros: 'my pros', + cons: 'my cons', + review_ratings_attributes: [ + { rating_id: ratings(:usability).id, value: 3 }, + { rating_id: ratings(:application_context).id, value: 3 }, + { rating_id: ratings(:content).id, value: 3 } + ] }, object_param_name => object.id end - end diff --git a/test/models/review_rating_test.rb b/test/models/review_rating_test.rb index 992c89b612c6798fe2d72bf02949058b32c45bce..97e231acd5a2273fcdf03b59a7f3849d74c319f8 100644 --- a/test/models/review_rating_test.rb +++ b/test/models/review_rating_test.rb @@ -16,7 +16,6 @@ class ReviewRatingTest < ActiveSupport::TestCase should belong_to :review should belong_to :rating - should validate_presence_of(:review) should validate_presence_of(:rating) should validate_inclusion_of(:value).in_array(Array(1..5)).with_message('Review Rating must be between 1 and 5.')