Last active
July 24, 2018 17:24
-
-
Save tansengming/1301128 to your computer and use it in GitHub Desktop.
Programming Notes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# joins with time range | |
time_range = (Time.now.midnight - 1.day)..Time.now.midnight | |
Client.joins(:orders).where(orders: { created_at: time_range }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# List comprehension | |
foods = ['broccoli', 'spinach', 'chocolate'] | |
eat food for food in foods when food isnt 'chocolate' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// selector with attributes | |
.option input[type=checkbox] { | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// go & channels | |
package main | |
import "fmt" | |
func sum(a []int, c chan int) { | |
sum := 0 | |
for _, v := range a { | |
sum += v | |
} | |
c <- sum // send sum to c | |
} | |
func main() { | |
a := []int{7, 2, 8, -9, 4, 0} | |
c := make(chan int) | |
go sum(a[:len(a)/2], c) | |
go sum(a[len(a)/2:], c) | |
x, y := <-c, <-c // receive from c | |
fmt.Println(x, y, x+y) | |
} | |
// maps | |
m := make(map[string]int) | |
m["Answer"] = 42 | |
// for each | |
for i, v := range pow { | |
fmt.Printf("2**%d = %d\n", i, v) | |
} | |
// new type declaration. Note curlies on vertex | |
type Vertex struct { | |
X int | |
Y int | |
} | |
func main() { | |
v := Vertex{1, 2} | |
v.X = 4 | |
fmt.Println(v.X) | |
} | |
// if with a statment | |
if v := math.Pow(x, n); v < lim { | |
return v | |
} | |
// Inside a function, the := short assignment statement can be used in place of a var declaration with implicit type. | |
// Outside a function, every construct begins with a keyword (var, func, and so on) and the := construct is not available. | |
// initializers | |
var i, j int = 1, 2 | |
var c, python, java = true, false, "no!" | |
// note the return | |
func split(sum int) (x, y int) { | |
x = sum * 4 / 9 | |
y = sum - x | |
return | |
} | |
// save on ints | |
func add(x, y int) int { | |
return x + y | |
} | |
// Useful | |
fmt.Println(12) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ES6 Arrows | |
class MyClass { | |
constructor() { | |
this.name = 'Max'; | |
setTimeout(() => { | |
// This prints "Max" since arrow functions bind to our current "this" context. | |
console.log(this.name); | |
}); | |
} | |
} | |
/// This is like writing: | |
var _this = this; | |
setTimeout(function() { | |
console.log(_this.name); | |
}); | |
// Logging Array Data | |
var langs = [ | |
{ name: "JavaScript", extension: ".js" }, | |
{ name: "HTML", extension: ".html" }, | |
{ name: "CoffeeScript", extension: ".coffee" }, | |
{ name: "SASS", extension: ".sass" } | |
]; | |
console.table(langs); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Pure Function as an Object (PFaaO) | |
## https://kellysutton.com/2017/09/13/embracing-functional-programming-in-ruby.html | |
class PayrollCalculator | |
def self.calculate(payroll) | |
new(payroll).calculate | |
end | |
def initialize(payroll) | |
@payroll = payroll | |
end | |
private_class_method :new | |
def calculate | |
PayrollResult.new( | |
payroll: payroll, | |
paystubs: paystubs, | |
taxes: taxes, | |
debits: debits | |
) | |
end | |
# all instance methods implicitly private because | |
# you can't call new | |
def paystubs | |
# ... | |
end | |
end | |
# Tap | |
## instead of | |
user = User.new | |
user.name = "John" | |
user | |
## try | |
User.new.tap { |user| user.name = "John" } | |
# pry instrospections https://blog.cognitohq.com/five-pry-features-every-ruby-developer-should-know/ | |
find-method xpath Nokogiri | |
stat Nokogiri::CSS.xpath_for | |
show-source Nokogiri::CSS.xpath_for | |
# Ruby 2.3 introduced the "squiggly heredoc" <<~. | |
# This will remove all the extra spaces introduced by indentation | |
# To generate a backtrace without raising an exception use the caller method like: | |
class Project | |
def foo | |
puts "=====================" | |
puts caller | |
end | |
# quick way to log where a function is getting called | |
def first_name | |
log_backtrace(:first_name) | |
profile.first_name | |
end | |
def log_backtrace(name) | |
filtered_backtrace = caller.select do |item| | |
item.start_with?(Rails.root.to_s) | |
end | |
Rails.logger.warn(<<-END) | |
A reference to an obsolete attribute #{name} at: | |
#{filtered_backtrace.join("\n")} | |
END | |
end | |
# Ruby automatically invokes the call method when the method name is omitted | |
Create.(params) == Create.call(params) | |
# getting source location of render | |
def index | |
p method(:render).source_location | |
render params[:id] | |
end | |
## reading from stdin | |
echo "bananas!" | ruby -e "puts STDIN.read" | |
### . If we run our script with the -n flag, Ruby will automatically loop over each line in STDIN. | |
### The current line is in the global variable $_. | |
ls | ruby -n -e 'puts $_.split(".").last' | |
## Splat -> converts arrays to method arguments | |
### As the argument | |
def say(what, *people) | |
people.each{|person| puts "#{person}: #{what}"} | |
end | |
say "Hello!", "Alice", "Bob", "Carl" | |
### to an argument | |
def add(a,b) | |
a + b | |
end | |
pair = [3,7] | |
add *pair | |
## Ruby delegators | |
class Queue | |
extend Forwardable | |
def initialize | |
@q = [ ] # prepare delegate object | |
end | |
# setup preferred interface, enq() and deq()... | |
def_delegator :@q, :push, :enq | |
def_delegator :@q, :shift, :deq | |
# support some general Array methods that fit Queues well | |
def_delegators :@q, :clear, :first, :push, :shift, :size | |
end | |
## Rake Directories | |
### Rakefile | |
directory 'output' | |
task something: ['output'] # will automatically create the output dir | |
## inject with powers | |
products.map(&:price).inject(0, &:+) | |
## Rake options | |
task :thing, [:foo] do |task, args| | |
puts args[:foo] # First argument | |
puts args.extras # The rest of the arguments | |
end | |
# $> rake thing[foo] | |
# foo | |
# $> rake thing[foo,extra1,extra2] | |
# foo | |
# extra1 | |
# extra2 | |
## Rake directories | |
# Additional rake files (with the file extension “.rake”) may be placed in rakelib directory | |
# located at the top level of a project (i.e. the same directory that contains the main Rakefile). | |
## Getting a random string | |
require 'securerandom' | |
puts SecureRandom.urlsafe_base64(50) | |
## Multi-line regexes | |
regexp = %r{ | |
start # some text | |
\s # white space char | |
(group) # first group | |
(?:alt1|alt2) # some alternation | |
end | |
}x | |
## CSV with headers | |
visitors = CSV.read('visitors.csv', headers: true) | |
visitors.count{|v| v['location'] =~ /San Francisco/} # => 168 | |
### Streaming version | |
CSV.open('visitors.csv', header: true) do |csv| | |
visitors = csv.each | |
visitors.count{|v| v['location'] =~ /San Francisco/ } | |
end | |
## Use x modifier for complex regexps. This makes them more readable and you can add some useful comments. Just be careful as spaces are ignored. | |
regexp = %r{ | |
start # some text | |
\s # white space char | |
(group) # first group | |
(?:alt1|alt2) # some alternation | |
end | |
}x | |
## Assignments and ifs | |
### good - shows intented use of assignment | |
if (v = array.grep(/foo/)) ... | |
### bad | |
if v = array.grep(/foo/) ... | |
### also good - shows intended use of assignment and has correct precedence. | |
if (v = self.next_value) == "hello" ... | |
# https://github.com/styleguide/ruby | |
## getting only direct methods (ignoring inherited ones) | |
obj.public_methods(false) | |
# Single line options split | |
count, default = options.values_at(:count, :default) | |
# Pry | |
# pry("friend":3)> nesting | |
# Nesting status: | |
# 0. main (Pry top level) | |
# 1. Hello | |
# 2. 100 | |
# 3. "friend" | |
# pry("friend":3)> jump-to 1 | |
# pry(main)> cd Pry | |
# pry(Pry)> ls -M --grep re | |
# Pry#methods: re readline refresh rep repl repl_epilogue repl_prologue retrieve_line | |
# pry(Pry):1> show-method rep -l | |
# pry(main)> cd Gem | |
# pry(Gem):1> show-doc try_activate | |
# pry(main) ri Array#each | |
## using in Rails | |
# pry -r ./config/environment | |
## In Ruby, &method calls you! | |
["1", "2", "3"].map(&method(:Integer)) | |
## Defaulting hashes | |
@filesize = Hash.new do |key, val| | |
val = calculate key | |
end | |
@filesize[arg] # will trigger calculate for keys that are not found | |
# Exceptions | |
## raising | |
def i_must_have_truth(value) | |
raise TypeError, 'You must give me truth' if value == false | |
end | |
## rescuing | |
begin | |
raise ZeroDivisionError, "Hello I am a random zero division error" | |
rescue ZeroDivisionError => e | |
p e.message | |
p e.backtrace | |
ensure | |
# do something | |
end | |
## new exceptions | |
class MyCrazyError < StandardError # DO NOT inherit from Exception | |
end | |
raise MyCrazyError, "I am a crazy new exception" | |
# ref: http://www.skorks.com/2009/09/ruby-exceptions-and-exception-handling/ | |
# Blocks | |
def func(x, &block) | |
block.call(1) | |
end | |
# is almost equivalent to | |
def func(x) | |
yield 1 | |
end | |
# yield just saves you the block.call | |
# Aliasing | |
class Microwave | |
def on | |
puts "The microwave is on" | |
end | |
alias :start :on | |
end | |
## ActiveSupport::Concern | |
module M | |
extend ActiveSupport::Concern | |
included do | |
some_class_method | |
end | |
module ClassMethods | |
# ... | |
end | |
module InstanceMethods | |
# ... | |
end | |
end | |
module B | |
extend ActiveSupport::Concern | |
include A | |
included do | |
class_method_from_module_a | |
end | |
end | |
## rspec | |
describe 'a feature' do | |
let(:var) { } # setup lazy vars | |
let!(:var) { } # setup vars | |
before { 'always triggers first' } # initialize | |
subject { } # subject under test | |
context 'when it is in a certain mode' do | |
it { should be_eligible_to_vote } # implicit subject | |
before { 'happens after top before' } | |
it 'should equal something' do | |
subject.should == 'something' | |
end | |
it 'should increment when incremented' do | |
expect { Counter.increment }.to change{ Counter.count }.by(1) | |
expect { Counter.increment }.to change{ Counter.count }.from(0).to(1) | |
expect {Counter.increment}.to_not change{Counter.count}.by(1) | |
end | |
it 'should not have an exception' do | |
lambda { subject }.should_not raise_error Validation::Error | |
end | |
end | |
context 'when testing controllers' do | |
before { subject } | |
subject { get :index } | |
it 'should be success' do | |
response.should be_success | |
end | |
it 'should render the right template' do | |
response.should render_template("new") | |
end | |
it 'should redirect to the right place' do | |
response.should redirect_to(menu_items_url) | |
end | |
its(:body) { should_not have_selector("#this-week", text: '13') } | |
end | |
end | |
## Explosions | |
'-' * 5 #=> "------" | |
['-'] * 5 #=> ['-', '-', '-', '-', '-'] | |
## Formatter | |
formatter = "%s %s %s %s" | |
puts formatter % [1, 2, 3, 4] | |
## Nokogiri | |
doc = Nokogiri::HTML(open("http://www.threescompany.com/")) | |
doc.css("dramas name").first # => "The A-Team" | |
doc.at_css("dramas name") # => "The A-Team" | |
doc.css('a').first.attributes['href'] | |
## Nokogiri Slop | |
doc = Nokogiri::Slop <<-EOXML | |
<employees> | |
<employee status="active"> | |
<fullname>Dean Martin</fullname> | |
</employee> | |
<employee status="inactive"> | |
<fullname>Jerry Lewis</fullname> | |
</employee> | |
</employees> | |
EOXML | |
# navigate! | |
doc.employees.employee.last.fullname.content # => "Jerry Lewis" | |
# access node attributes! | |
doc.employees.employee.first["status"] # => "active" | |
# use some css! | |
doc.employees.employee("[status='active']").fullname.content # => "Dean Martin" | |
## Compiling gem on other machine | |
#> gem install rake-compiler | |
#> gem unpack some-gem-with-native-extensions | |
#> rake native gem | |
## obj.present? | |
obj.present? == !obj.nil? && !obj.empty? | |
## system vs exec | |
exec gets out of the current thread. Which is usually not what you want. | |
## Object Exists? | |
# to check if object exists or is defined. | |
defined?(Post) | |
## Unit Testing | |
require 'test/unit' | |
class TC_MyTest < Test::Unit::TestCase | |
# def setup | |
# end | |
# def teardown | |
# end | |
def test_fail | |
assert(false, 'Assertion was false.') | |
end | |
end | |
## urlencode and htmlencode | |
require 'cgi' | |
CGI.escape(url) | |
CGI.unescape(name_encoded) | |
CGI.escapeHTML(url) | |
CGI.unescapeHTML(name_encoded) | |
## Fastercsv | |
# Reading | |
FasterCSV.foreach("path/to/file.csv") do |row| | |
# use row here... | |
end | |
arr_of_arrs = FasterCSV.read("path/to/file.csv") | |
# Writing | |
FasterCSV.open("path/to/file.csv", "w") do |csv| | |
csv << ["row", "of", "CSV", "data"] | |
csv << ["another", "row"] | |
end | |
FCSV { |csv_out| csv_out << %w{my data here} } # to $stdout | |
FCSV(csv = "") { |csv_str| csv_str << %w{my data here} } # to a String | |
Ref | |
## Openstruct | |
require 'ostruct' | |
record = OpenStruct.new | |
record.name = "John Smith" | |
puts record.name # -> "John Smith" | |
puts record.address # -> nil | |
## Logger | |
require 'logger' | |
Log = Logger.new(STDOUT); Log.level = Logger::INFO | |
## Stripping HTML | |
str.gsub(/<\/?[^>]*>/, "") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Sort on steroids | |
sort -n -t',' -k3 uniqMovie.csv | |
# -n to inform its numerical sorting and not lexical sorting | |
# -t specifies delimiter which is comma is this case | |
# -k indicates which column, 3rd in our case | |
# Loop forever | |
while true; do sleep 5; echo 1; done | |
# for with ranges | |
for i in {1..7} | |
do | |
#stuff | |
done | |
# git grep files | |
git grep abc -- '*.rb' | |
# generating random chars | |
head -c 9 /dev/urandom | base64 - | |
# pipe std and sterr to a file | |
some_command 2>&1 | tee -a a.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// For and If | |
let individualScores = [75, 43, 103, 87, 12] | |
var teamScore = 0 | |
for score in individualScores { | |
if score > 50 { | |
teamScore += 3 | |
} else { | |
teamScore += 1 | |
} | |
} | |
// Escaping | |
let apples = 3 | |
let oranges = 5 | |
let fruitSummary = "I have \(apples + oranges) pieces of fruit." | |
// Casting | |
let label = "The width is " | |
let width = 94 | |
let widthLabel = label + String(width) | |
// Variables and Constants | |
var myVariable = 42 | |
myVariable = 50 | |
let myConstant = 42 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# appending x or f to rspec | |
xit 'uses `xit` instead of `it` skips the spec' do | |
end | |
fit 'appending f makes the spec focus' do | |
end | |
# Ranges in AR | |
User.where(created_at: 1.day.ago..Time.now) # SELECT "users".* FROM "users" WHERE ("users"."created_at" BETWEEN '2016-06-29 15:24:55.565740' AND '2016-06-30 15:24:55.565975') | |
# Sidekiq | |
SmsWorker.perform_async(model.id,model.class.to_s) | |
Services::Notification::Worker.perform_in(DELAY, source.id, source_klass, :ios) | |
UserMailer.delay.welcome_email(@user.id) | |
UserMailer.delay_for(DELAY).booking_email(model.id, recipient.id) | |
# RSpec stubs and mocks | |
expect_any_instance_of(CondoManager::Resources::Account).to receive(:save) | |
allow_any_instance_of(CondoManager::Client).to receive(:parse_resource).and_raise(CondoManager::Error) | |
# Rails load order | |
# script/rails | |
# config/boot.rb | |
# config/application.rb | |
# config/environment.rb | |
# config/initializers/*.rb (In alphabetic order) | |
# stubbing exceptions on rspec | |
context 'when connection is reset' do | |
before { Purchase.any_instance.stub(:purchase).and_return{ raise Errno::ECONNRESET } } | |
its(:body) { should have_content 'payment servers are currently busy' } | |
end | |
# end of deploy sanity check | |
# ./script/rails runner -e staging 'exit Student.first ? 0 : 1'" | |
## checking for locals within partials | |
# <% if local_assigns.has_key? :headline %> | |
# Headline: <%= headline %> | |
# <% end %> | |
# http://api.rubyonrails.org/classes/ActionView/Base.html | |
## Finders with errors when not found | |
User.find_by_name! 'nonexistent!' | |
## Rails Delegation | |
class Greeter < ActiveRecord::Base | |
def hello | |
"hello" | |
end | |
end | |
class Foo < ActiveRecord::Base | |
belongs_to :greeter | |
delegate :hello, :to => :greeter | |
end | |
Foo.new.hello # => "hello" | |
### Also | |
Person = Struct.new(:name, :address) | |
class Invoice < Struct.new(:client) | |
delegate :name, :address, :to => :client, :prefix => true | |
end | |
john_doe = Person.new("John Doe", "Vimmersvej 13") | |
invoice = Invoice.new(john_doe) | |
invoice.client_name # => "John Doe" | |
invoice.client_address # => "Vimmersvej 13" | |
## Active Record Serialize | |
class User < ActiveRecord::Base | |
serialize :preferences | |
end | |
user = User.create(:preferences => { "background" => "black", "display" => large }) | |
User.find(user.id).preferences # => { "background" => "black", "display" => large } | |
# Or, specify a class | |
class User < ActiveRecord::Base | |
serialize :preferences, OpenStruct | |
end | |
user = User.new | |
user.preferences.theme_color = "red" | |
## rescue_from | |
class SomeController < ApplicationController | |
rescue_from User::NotAuthorized, :with => :deny_access # self defined exception | |
rescue_from ActiveRecord::RecordInvalid, :with => :show_errors | |
rescue_from 'MyAppError::Base' do |exception| | |
render :xml => exception, :status => 500 | |
end | |
end | |
## Migrations | |
def up | |
say_with_time "Updating salaries..." do | |
Person.find(:all).each do |p| | |
p.update_attribute :salary, SalaryCalculator.compute(p) | |
end | |
end | |
end | |
## respond_to | |
respond_to do |format| | |
format.json { render json: nil, status: :ok } | |
end | |
# btw, don't use to_json | |
# http://jonathanjulian.com/2010/04/rails-to_json-or-as_json/ | |
respond_to do |format| | |
format.json { render :json => items.as_json(:only => [:id], :methods => [:label, :value])} | |
end | |
## Advanced HAML | |
# %div[@user, :greeting] -> <div class='greeting_crazy_user' id='greeting_crazy_user_15'> | |
# & I like #{"cheese & crackers"} -> I like cheese & crackers | |
# != "I feel <strong>!" # unescapes HTML | |
## ActiveRecord | |
add_index "subscriptions", ["user_id", "content_id"], :unique => true # migration | |
validates_uniqueness_of :user_id, :scope => :content_id # model | |
## Rails Responders | |
# http://api.rubyonrails.org/classes/ActionController/Responder.html | |
def create | |
@user = User.new(params[:user]) | |
flash[:notice] = 'User was successfully created.' if @user.save | |
respond_with(@user) | |
end | |
# custom return | |
def create | |
@project = Project.find(params[:project_id]) | |
@task = @project.comments.build(params[:task]) | |
flash[:notice] = 'Task was successfully created.' if @task.save | |
respond_with(@project, @task, :status => 201) | |
end | |
# with a block | |
def create | |
@project = Project.find(params[:project_id]) | |
@task = @project.comments.build(params[:task]) | |
respond_with(@project, @task, :status => 201) do |format| | |
if @task.save | |
flash[:notice] = 'Task was successfully created.' | |
else | |
format.html { render "some_special_template" } | |
end | |
end | |
end | |
## as_json | |
User.find(1) | |
user.as_json # => {"id": 1, "name": "Konata Izumi", "age": 16, "created_at": "2006/08/01", "awesome": true} | |
user.as_json(:only => [ :id, :name ]) # => {"id": 1, "name": "Konata Izumi"} | |
user.as_json(:except => [ :id, :created_at, :age ]) # => {"name": "Konata Izumi", "awesome": true} | |
user.as_json(:methods => :permalink) # => {"id": 1, "name": "Konata Izumi", "age": 16, "created_at": "2006/08/01", "awesome": true, "permalink": "1-konata-izumi"} | |
user.as_json(:include => :posts) | |
user.as_json(:include => { :posts => { :include => | |
{ :comments => { :only => :body } }, | |
:only => :title } | |
} | |
) | |
## production.rb hint to serve to multiple asset hosts | |
config.action_controller.asset_host = 'assets%d.example.com' | |
## content_for (with HAML) | |
# - content_for :controls do | |
# %ul | |
# %li Do this | |
# %li Do that | |
# = yield :controls | |
# %table | |
# … | |
# = yield :controls | |
## Inherited Resources | |
def create | |
create! { products_path } | |
end | |
class TalksController < InheritedResources::Base | |
belongs_to :track | |
respond_to :json, :only => [:index] | |
def index | |
respond_with(collection, :methods => [:attachment_type, :rate_average], :include => { :participations => { :include => :speaker }, :attachments => {}, :location => {} }) | |
end | |
end | |
# Flash messages in en.yml | |
# en: | |
# flash: | |
# reviews: | |
# create: | |
# notice: "Your review has been created!" | |
## ActiveAdmin | |
ActiveAdmin.register Event do | |
menu :if => :super_admin? | |
belongs_to :account | |
belongs_to :other, :optional => true | |
form do |f| | |
f.inputs do | |
f.input :name | |
f.input :start_date, :as => :datepicker | |
end | |
# remember to add 'accepts_nested_attributes_for' in user.rb | |
f.has_many :pets do |p| | |
p.input :name | |
p.input :animal, :as => :select, :collection => %w{Cat Dog} | |
end | |
f.buttons | |
end | |
show do | |
attributes_table :name, :slug | |
panel "Logo" do | |
image_tag(resource.logo.url) if resource.logo.present? | |
end | |
attributes_table do | |
row :trainer do | |
pretty_format constraint.trainer | |
end | |
end | |
resource.constraints.each do |constraint| | |
panel 'Constraint' do | |
attributes_table_for constraint, :trainer | |
end | |
end | |
end | |
index do | |
column :name | |
column(:avatar) { |resource| resource.avatar.present? ? status_tag('YES', :ok) : status_tag('NO', :warning) } | |
default_actions | |
end | |
filter :name | |
action_item :only => :show do | |
link_to 'Upload Attendees', new_admin_event_attendee_csv_path(resource) | |
end | |
controller do | |
around_filter :set_timezone, :only => [:create, :update] | |
private | |
def set_timezone | |
orig_timezone = Time.zone | |
Time.zone = params[:event][:timezone] | |
yield | |
ensure | |
Time.zone = orig_timezone | |
end | |
end | |
end | |
# With Formtastic | |
# <%= semantic_form_for resource, :url => resource.new_record? ? collection_path : resource_path, :html => {:multipart => true} do |f| %> | |
# <%= f.inputs do %> | |
# <%= f.input :account_id, :input_html => {:value => current_admin_user.id}, :as => :hidden %> | |
# <%= f.input :start_date, :input_html => {:class => 'datepicker'}, :as => :string %> | |
# <%= f.input :post_checkin_image, :as => :file %> | |
# <% end %> | |
# <%= f.buttons %> | |
# <% end %> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment