-
Fix the following snippet. Given a collection of 1000 draft Articles, update all of them to be published
Post.where(status: :draft).each { |p| p.update_attributes(status: :published}
#1
Post.where(status: :draft).update_all(status: :published)
#2 (just more readable)
class Post < ActiveRecord::Base
scope :draft, -> { where(status: :draft) }
end
Post.draft.update_all(status: :published)
- JSON Response
class UsersController < ApplicationController
def index
@users = User.includes(posts: [:comments])
# User: id, username, email
# Post: id, title
# Comment: id, content
render json: @users,
only: [:id, :username, :email],
include: {
posts: { only: [:id, :title],
include: {
comments: { only: [:id, :content] }
}
}
}
end
end
I wasn't able to add the root key on the JSON response output. Also, I considered using the "active_model_serializers" gem and use Serializer objects for better customization and maintainability.
This was the best I could do regarding this problem. (I need to read up more on serializing :D). And I needed to send this answers before the deadline.
-
What is
self.included
? How would you use it in mixins?self.included
is called by Ruby when a module is included in a class. This method is defined in Ruby'sModule
class.This method allows us to execute code in the context of the including class. In turn, it makes our module mixins much more reusable and makes our code more DRYer.
Here's are 2 examples:
# Example 1: Shameless/lousy implementation of ActiveRecord :P module Persistence module ClassMethods def create puts ".create class method called by #{self}" end def create! puts ".create! class method called by #{self}" end end def self.included(klass) klass.extend ClassMethods end def destroy puts "#destroy called in #{self}" end def save; end def update; end end class Product include Persistence end class Client include Persistence end class Supplier include Persistence end Product.create p = Product.new p.save puts Client.create Client.new.destroy puts Supplier.create Supplier.new.destroy
# Example 2: A polymorphic Comment model that is referenced by 3 models. class Comment < ActiveRecord::Base belongs_to :commentable, polymorphic: true end module Commentable def self.included(klass) klass.class_eval do has_many :comments, as: :commentable # more shared behavior as functionality grows more complex end end end class Post < ActiveRecord::Base include Commentable end class Page < ActiveRecord::Base include Commentable end class SupportTicket < ActiveRecord::Base include Commentable end Post.first.comments Page.first.comments SupportTicket.last.comments
-
Why is it bad to use
rescue
in the following manner? What do you understand about the ruby exception hierarchy?begin do_something() rescue Exception => e puts e end
The following code above is not advisable because it uses
rescue
to catch a genericException
object. This will rescue every exception, from errors in your app and even simple syntax errors you've missed. It is viewed as a lazy way to do error handling.Besides, this would not be very helpful to pinpoint the exact reason why your code blew up in the first place. It's best to be specific about what error/error object to anticipate and catch/handle them properly.
What do you understand about the ruby exception hierarchy?
The Ruby exception hierarchy is made up of classes that inherits from the
Exception
class. A number of theses classes are grouped together based on similarity.Take for example the
NameError
and theNoMethodError
classes. They're grouped together under theStandardError
class because of their similarity to handling undefined variables or methods.NameError
is raised if Ruby can't determine a bareword/identifier if it's defined as a variable or a method. On the other hand,NoMethodError
inherits fromNameError
, which is raised when you call an undefiend method.Here's an example of the same bareword, raising those two errors:
# "hero" is our undefined bareword hero # => raises NameError; Ruby can't determine if its a variable or a method hero() # => raises NoMethodError; Ruby understands this is a method because of the added parentheses (to explicity state that it's a method)
Also, the
StandardError
object/class is the default when using therescue
clause without specifying an exception to catch. Catching exceptions that inherit from theStandardError
class mostly suffice for the error handling needs of our Ruby programs.
SELECT g.id, g.transaction_id, g.glove_type
FROM gloves g
LEFT JOIN transactions t
ON g.transaction_id = t.id
GROUP BY g.transaction_id, g.glove_type
HAVING COUNT(g.transaction_id) > 1
ORDER BY g.id;