Skip to content

Instantly share code, notes, and snippets.

@nashby
Created July 24, 2011 08:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nashby/1102421 to your computer and use it in GitHub Desktop.
Save nashby/1102421 to your computer and use it in GitHub Desktop.

InteractiveCU is a simple interactive create and update for AR.

Examples:

Create:

ruby-1.9.2-p180 :007 > User
 => User(id: integer, name: string, created_at: datetime, updated_at: datetime) 
ruby-1.9.2-p180 :008 > User.interactive_create # or User.ic

==New User==

name: nash
  SQL (0.8ms)  INSERT INTO "users" ("created_at", "name", "updated_at") VALUES (?, ?, ?)  [["created_at", Sun, 24 Jul 2011 08:49:26 UTC +00:00], ["name", "nash"], ["updated_at", Sun, 24 Jul 2011 08:49:26 UTC +00:00]]
 => true 

Update:

ruby-1.9.2-p180 :009 > User.last.interactive_update # or User.last.iu

==Old User==

id: 8
name: nash
created_at: 2011-07-24 08:49:26 UTC
updated_at: 2011-07-24 08:49:26 UTC

==New User==

name: updated_nash
   (0.5ms)  UPDATE "users" SET "name" = 'updated_nash', "updated_at" = '2011-07-24 08:50:28.794082' WHERE "users"."id" = 8
 => true 

It shows you validation errors:

ruby-1.9.2-p180 :010 > User.last.iu

==Old User==

id: 8
name: updated_nash
created_at: 2011-07-24 08:49:26 UTC
updated_at: 2011-07-24 08:50:28 UTC

==New User==

name: 

Something went wrong:

name:  <------ can't be blank 
 => nil 
module InteractiveCU
NOT_INTERACTIVE = %w(id created_at updated_at)
def self.included base
base.extend(ClassMethods)
end
def self.read_attributes attrs
params = {}
attrs.each do |name, value|
unless NOT_INTERACTIVE.include? name
print "#{name}: "
params[name] = gets.strip
end
end
params
end
def self.output(options)
puts
puts "==#{options[:status]} #{options[:name]}=="
puts
end
def self.validate_errors(obj, attrs)
puts
puts "Something went wrong:"
puts
obj.errors.messages.each do |attr, error|
puts "#{attr}: #{obj.send(attr)} <------ #{error.join(', ')} "
end
nil
end
def interactive_update
InteractiveCU::output :status => "Old", :name => self.class.name
attributes.each do |name, value|
puts "#{name}: #{value}"
end
InteractiveCU::output :status => "New", :name => self.class.name
new_attributes = InteractiveCU::read_attributes attributes
self.attributes = new_attributes
unless self.valid?
InteractiveCU::validate_errors self, new_attributes
else
save
end
end
alias_method :iu, :interactive_update
module ClassMethods
def interactive_create
InteractiveCU::output :status => "New", :name => self.name
obj = self.new
new_attributes = InteractiveCU::read_attributes self.attribute_names
obj.attributes = new_attributes
unless obj.valid?
InteractiveCU::validate_errors obj, new_attributes
else
obj.save
end
end
alias_method :ic, :interactive_create
end
end
class ActiveRecord::Base
include InteractiveCU
end
@joshk
Copy link

joshk commented Jul 25, 2011

This is pretty cool and handy

@ericgj
Copy link

ericgj commented Jul 28, 2011

Nice. How about passing attributes in to #iu, #ic ? Often you only want to edit one, or a few. And/or a way of skipping when prompted.

@nashby
Copy link
Author

nashby commented Jul 28, 2011

Thanks, guys!
@ericgj, it's a good idea about attributes skipping. I'll look into it.

@tdavydik
Copy link

Wow, that's awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment