[Rails tips] validates uniqueness scope 的應用

在一些情況下我們可能會需要驗證某個資料是只能出現一次的,在 MySQL 有一種 index 叫做 unique (唯一鍵)的索引可以處理這種驗證,在 Rails 中可以用 add_index :xxx, :ooo, :unique => true 的方式替它打上唯一鍵。

但是如果不想用索引來驗證,想要透過 Rails 端來處理這件事的話,則可以用 validates :xxx, :uniqueness => true 來處理,一樣可以處理唯一資料,只是這種驗證方式略顯單調,因為它預設的情境是:整張資料表只能有這種資料一次。這樣有時候會不能符合我們所需要的情境,譬如說:

某個 user 只能夠各建立一個 service_typesay_hellosay_hi 的資料時,我們如果用: validates :service_type, :uniqueness => true 來處理就會炸掉,這時候我們就可以手動加上 :scope 來綁定驗證條件:

validates :service_type, :uniqueness => { :scope => :user_id }

這樣一來,就能夠確保每個 user 都可以各建立一次 service_typesay_hello 以及 say_hi 的資料了。

用 FileAPI 檢查圖片長寬

imageDimension = 685
checkFileSizeAndUpload = (data) ->
  uploadable = no
  file = data.files[0]
  fileReader = new FileReader
  fileReader.onload = ->
    image = new Image

    image.onload = ->
      if image.width >= imageDimension and image.height >= imageDimension
        data.submit()
        alertify.success "檔案上傳中,請稍後"
      else
        alertify.alert "噢!這張圖太小了。請選擇圖片尺寸至少 #{imageDimension}x#{imageDimension} 像素上傳。"

    image.src = fileReader.result

  fileReader.readAsDataURL(file)

Rails with Time zone 筆記

做一個國際型的社群網站多少都會碰到時區問題,而在 Rails 裡面這部分算是還蠻容易就可以處理的了。

取得日期與時間

在 Rails 中,通常會透過以下幾種敘述得到日期或者日期時間

Time.now
Date.today

但是這種方式取得的時間都是以「執行端」為主的時間,抓的基本上就是系統時間,所以一般在台灣的主機跑的都是 +08:00 ,假設有日本、韓國或者夏威夷等地方的使用者想要取得他們當地的時間的話用這種方式絕對會出問題。

所以就必須用另外一種方式來取得時間,就是:

Time.current
Date.current

如此一來抓到的時間點才會是根據不同時區而做過調整的。然而,有一些 API 本身就會跟著時區設定跑,像是:

1.days.ago
10.days.from_now

諸如此類這種的就會根據 Rails 的 time zone 設定而決定當前的時區,設定的方式就是在 config/application.rb 中編輯 config.time_zone = 'Taipei' 就可以設定台灣時區。

Rails 支援很多的時區設定,但是都是根據名稱為主,而想要有詳細的列表可以在命令列(終端機)執行 rake time:zones:all 檢查。

rake time:zones:all

然而有的時候可能會需要過濾一下一些時區,或者自定時差來列表,這時候可以用類似以下方式取得:

rake time:zones:us # 取得美國地區所有的可設定值 (美國跨好幾個時區)
rake time:zones:local # 取得你當前時區的所有可設定值
rake time:zones:all OFFSET=-3 # 取得時區偏移量為 -3 小時的

在 Controller 該怎麼設定

所以,當我們希望加上自訂時區設定的時候,會希望可以自動生效時區設定,這時候我們就可以用 around_action (Rails 4 之前的版本是 around_filter) 來做設定。

class ApplicationController < ActionController::Base
  around_filter :setup_timezone, :if => :current_user?
  
  def setup_timezone(&block)
    Time.use_zone(current_user.time_zone, &block)
  end
end

所以,要記得替你的 User model 加上 time_zone 這個欄位。

參考文章

大六壬筆記

排盤步驟 (此參考「大六壬預測學」一書,第三章,頁數第 95 頁)

  1. 製作天地盤
  2. 佈天乙貴人順逆飛十二天將
  3. 起四課
  4. 發三傳

月將

天盤要先知道月將,取得月將的方式則是看節氣的中氣,月將排列為:

  • 雨水 => 春分:亥
  • 春分 => 穀雨:戌
  • 穀雨 => 小滿:酉
  • 小滿 => 夏至:申
  • 夏至 => 大暑:未
  • 大暑 => 處暑:午
  • 處暑 => 秋分:巳
  • 秋分 => 霜降:辰
  • 霜降 => 小雪:卯
  • 小雪 => 冬至:寅
  • 冬至 => 大寒:丑
  • 大寒 => 雨水:子

今天 (2014/02/22) 是小雨氣 (立春節) ,所以要看小雨 => 春分,所以今天的月將是亥,在紙上寫下「月將:亥」

知道月將後我們要有「占時」作為一個排天盤的重要依據,而取得占時的方式有以下幾種:

  1. 抽竹籤:製作十二支或者倍數的竹籤,然後寫上地支(時辰),然後占卜時心裡默念問題,接著空靈清澈時抽一籤就為占時
  2. 如果幫人占,請對方隨便報一個地支(時辰),如果報「卯」則以「卯」為占時
  3. 梅花易取卦法:梅花易有一種取卦方式很有趣,請對方任意報出一個數字後除以一定數取餘數即可當作卦來使用,若用於六壬則將數字除以十二取餘數即可
  4. 觸機法:事件發生的時間點當作占時,或者觸發某件事情的時候的時辰也可。

假設占時為卯,就將月將擺在地盤的卯上,然後順時針排餘下的十一個地支

月將為亥,所以在地盤上找到「卯」的位置,然後順時鐘繼續寫:子、丑、寅 ...

月建

日干支

即是求占當日的干支,以日干當作主體(就是自己),支代表客體(求占的事情、對方)。

占時

空亡

地盤

地盤是固定的

天盤

天盤根據占時來決定擺放位置,假設占時卯就是把東西放在地盤上的卯。

而要被擺放的東西是月將,所以就是把月將擺在占時所代表的地盤上,然後順時鐘寫剩下的十一個地支。

十干寄宮

接下來就是起四課,但是在講起四課之前要先講一下十干寄宮。

十天干會落在地盤上的某些位置,這個可以稍微背一下,然後歌訣:

甲寄寅兮乙寄辰,丙戊寄巳不須論,丁己寄未庚申上,辛戌壬亥記取真,問到癸兮丑宮坐,分明不用四仲神。

四仲神:子、午、卯、酉

簡單的說就是四仲神不會有任何天干落下,然後甲放在寅宮、乙放在辰宮 ... 依此類推。

十二天將

天乙貴人(十二神將)有:
貴人、螣蛇、朱雀、六合、勾陳、青龍、天空、白虎、太常、玄武、太陰、天后

這個順序是到時候順佈、逆佈時要寫的順序,有點像是奇門遁甲佈三奇六儀那樣,但是不需要根據陰陽局決定順佈三奇逆佈六儀或者逆佈三奇順佈六儀,六壬中排十二天將有一個規則,等等會提到

在盤上可以簡寫十二神將的名字,照順序就是:「貴、蛇、朱、合、勾、青、空、白、常、玄、陰、后」

十二神將排列會需要根據占卜當下的時間決定從哪裡開始、怎麼佈,主要的時間是看太陽是否還存在在地平線上來決定陰陽(夜晝),而排列的方式是這樣:

不太好記憶對吧?這邊提供晝夜貴人歌:

晝:甲羊戊庚牛、乙猴己鼠求、丙雞丁豬位、壬兔癸蛇游、六辛逢虎上、陽貴日中儔
夜:甲牛戊庚羊、乙鼠己猴鄉、丙豬丁雞位、壬蛇癸兔藏、六辛逢午馬、陰貴夜時當

甲羊戊庚牛的意思是:羊的地支是未,把未放在陽貴的甲,然後戊與庚放上牛的地支(丑)

依此類推

然後我們看一下占卜的那天的日干支是什麼,假設當天是甲子日:

  • 日干:甲
  • 日支:子
  • 時支:子時

占卜時間是子時是太陽的下班時間,所以這個屬於夜占,要採用夜貴排列方式
日干甲夜貴人對表後發現甲 => 丑,所以對照天盤上的丑我們寫上「貴」。

再來是排列的方式,這個部分會影響貴人順飛或逆飛:

落宮 地盤 地盤 地盤 地盤 地盤 地盤
順飛
逆飛

在這個例子裏面我們的貴人落在天盤丑上,而丑是落在地盤寅上,所以我們順時鐘擺上十二神將,所以會是這樣 (第一個為天盤,第二個為地盤,第三個為神將):

辰巳合 巳午勾 午未龍 未申空
卯辰朱 申酉白
寅卯蛇 酉戌常
丑寅貴 子丑后 亥子陰 戌亥玄

四課

接著起四課,每一課都有上下兩神,寫法會類似這樣 (最左邊為第四課)

第一課:下神就是占卜日的日干,上神則是查表後所得到的寄宮當前的天盤。
第二課:下神就是第一課的上神,接著找出下神所在宮位的天盤是誰。
第三課:下神就是占卜日的日支,上神則是下神位置的天盤是誰。
第四課:下神就是第三課的上神,上神則是下神位置的天盤是誰。

舉例來說,日干為甲日支為子 (看一下上面包含十二神將的範例盤):

第一課:甲寄寅宮,地盤的寅宮的天盤這時停留的是丑,所以第一課是:丑甲 (把天盤擺在上神,查詢用的擺在下神)
第二課:把第一課的上神 (丑) 拿來當下神,接著下神這時是丑了,查一下地盤丑的天盤這時是誰停留。這時停在地盤丑上面的天盤是子,所以第二課是:子丑
第三課:同第一課,不過不需查表。這時候我們直接把日支當下神,日支是子。在地盤的子宮上面看天盤是誰停留。天盤這時是亥,所以第三課為亥子。
第四課:同第二課的做法,把第三課的上神抓來當下神,查一下天地盤後看出停留在地盤亥上的天盤這時是戌,所以第四課是:戌亥。

好了,所以寫出來就會是:

三傳

四課取完,根據九宗法的方式來發三傳,而九宗法的意思就是有九種法則,分別是:

  1. 賊剋法
  2. 知一法
  3. 涉害法
  4. 遙剋法
  5. 昂星法
  6. 別責法
  7. 八專法
  8. 伏吟法
  9. 返吟法

根據陰陽五行相生相剋的方式來決定是哪一種法則,然後來看出該怎樣處理,這個部分就之後再談了。

伏吟法

天地盤相合(就是天盤子擺在地盤子上)若第一課無剋,則剛日取日上神做發用,柔日取辰上神發用初傳。

中傳為初傳的刑,末傳為中傳的刑。如果初傳自刑,取日上神發用的(剛日)就以辰上神為中傳,末傳為中傳的刑;如果是以辰上神發用的(柔日),則以日上神為中傳。

若遇第一課有賊剋,以賊剋法發用初傳,中末傳則如同上述那樣以刑取得。

返吟法

遁干

查求占日的干支在哪一旬,然後對照三傳內初、中、末各自的天干為哪個,這個就是遁干。

年命

重要神煞

福佑之神,有天德、月德、日德(又稱干德)、支德。其中,天德、月德皆隨月而變動。

月別
天德
月德

祿

驛馬

桃花

Rails 4 + SettingsLogic + Googl 製作短網址功能

Why?

啊就因為專案需要啊,不然咧 ... XD

How?

請仔細看本教學

Okay, first?

各位可以到 https://github.com/hechien/example-short-url-rails clone 這個專案下來看看 :)

Requirements

我們會需要以上三個 Gem 套件,所以請在 Gemfile 中加上

gem 'settingslogic'
gem 'googl'

Okay, let's go!

第一次

在這個 Project 中我會建立一個 Article 來存文章,然後在儲存之後把文章網址轉為短網址。

打開 app/controllers/articles_controller.rb 然後在建立文章之後寫上

url = Googl.shorten(article_url(@article)).short_url
@article.update({ short_url: url })

Refactor 1

這樣就能夠把短網址弄出來了。

不過這樣寫其實挺亂的,所以我們拆出來另外寫。

def create
  respond_to do |format|
    if save_article
      format.html { redirect_to @article, notice: 'Article was successfully created.' }
      format.json { render action: 'show', status: :created, location: @article }
    else
      format.html { render action: 'new' }
      format.json { render json: @article.errors, status: :unprocessable_entity }
    end
  end
end

private

def save_article
    @article = Article.create(article_params)
  if @article.persisted?
    @article.update({ :short_url => Googl.shorten(article_url(@article)).short_url })
    return true
  end
  false
end

這樣的確乾淨多了,不過如果想要有一個監控 URL 點擊的次數的話可能就得登入自己的 Google 帳號,那這時候就得傳入自己的帳號密碼進去了,這邊我的資料是

(當然是假的,不必想登入)

加上帳密的寫法

client = Googl.client('foobar@gmail.com', 'foofoofoobarbarbar')
@article.update({ :short_url => client.shorten(article_url(@article)).short_url })

這樣一來就能使用登入過的帳號記錄了。

Refactor 2

可是,這樣子大家會看到帳號密碼啊 ... 安全性瞬間將到最低點!所以我們可以透過 SettingsLogic 來協助處理這件事。

建立 SettingsLogic model

app/models/ 底下建立一個 settings.rb

# app/models/settings.rb

class Settings < Settingslogic
  source "#{Rails.root}/config/application.yml"
  namespace Rails.env
end

建立 application.yml

然後,到 /config/ 底下建立 application.yml 這個檔案,並且輸入以下內容 (其實你可以用貼的)

# config/application.yml

defaults: &defaults

  googl:

    username: "foobar@gmail.com"

    password: "foofoofoobarbarbar"



development:

  <<: *defaults



test:

  <<: *defaults



production:

  <<: *defaults

存檔離開

修改 Googl 的設定方式

client = Googl.client(Settings.googl.username, Settings.googl.password)

好了,搞定,然後記得要在 .gitignore 裡面加上 /config/application.yml

蝦咪?你要把 application.yml 存到 Git 內?

嗯 ... 那還有一招,不過我們先把 /config/application.yml.gitignore 裡面移除吧!

然後,打開你的 application.yml 後,改為以下內容:

defaults: &defaults

  googl:

    username: <%= ENV["GOOGL_USERNAME"] %>

    password: <%= ENV["GOOGL_PASSWORD"] %>


development:

  <<: *defaults



test:

  <<: *defaults



production:

  <<: *defaults

然後再去設定環境變數,把帳號密碼設定進去就好了。

** UPDATED **

Refactor 3 - Service Object

xdite 建議拆成 Service Object 來處理,我就練習 & 筆記一下 XD

Steps

  1. app 資料夾底下建立一個 services 資料夾
  2. 新增 services/shorten_url.rb
  3. 新增底下的程式碼
    class ShortenUrl
    def initialize @client = Googl.client(Settings.googl.username, Settings.googl.password) end

    def shorten(url)
    @client.shorten(url).short_url
    end
    end


    1. 修改 app/controllers/articles_controller.rb
      def create
      @article = Article.new(article_params)
      respond_to do |format|
      if @article.save
        @article.update({ :short_url => ShortenUrl.instance.shorten(article_url(article)) })
      end
      end
      end
      
    2. 刪除掉最底下的 save_article

    我後來的版本還有替 ShortenUrl 加上 Singleton 功能,這個部分加不加就見仁見智了。

CSS 3 的 not Selector 運用實例

我遇到有一個 case 是這樣的:有兩個 QR Code 的顯示區塊分別是 for iOS & for Android 。今天可能客戶會只顯示 iOS 的 QR Code ,這時要讓 iOS 的 QR Code 可以正常顯示在正中央。如果 iOS & Android 同時都出現則各佔一半。

這個東西剛看到的時候還愣了一下,原本想說讓獨自出現的那個圖片加上 only-me 這個 class 然後設定置中 (後面講解法),但是後來想說可以用 not 實作看看,所以就有了以下的解法 (當然用 only-me 這種解法會比較漂亮)

步驟一:打上 hide-me class

def render_qrcode_block
  ...
  
  classes = ["qrcode"]
  classes << "hide-me" unless url.blank?
  
  ...
end

步驟二:CSS 中加上 .hide-me

.qrcode {
  &.hide-me {
    display: none;
  }
  
  &:not(.hide-me) {
    float: center;
    text-align: center;
  }
}

步驟三:沒有步驟三了

如此一來,實際的呈現效果就會正常。

但是,不夠好啊 ...

  • 改法一:因為這樣變成我要多寫一個 .hide-me 的 Class 設定,所以可以改寫 Helper ,當沒有 URL 的時候就不要輸出該區塊,然後拿掉 .hide-me 的 CSS 設定。
  • 改法二:用 only-me 搭配改法一的方式,然後只設定 only-me 的 CSS 就好

我會比較推薦改法二,乾淨很多 ... 不過 CSS 3 的 not 的確很好用。

Rails 4 + Compass + Susy + Sassy Buttons

做個筆記 ...

在 Rails 4 之後好一大段時間, compass-rails 整個是爛的,爛到深處無怨尤 ... 後來在最近 compass-rails 推出 1.1.2 版之後才好了起來,今天是 2014-01-22 ,我安裝了 1.1.3 版。

步驟

  1. Gemfile 內加上

    gem 'compass-rails', '~> 1.1.3'
    gem 'susy'
    gem 'sassy-buttons'
    
  2. bundle install

  3. touch tmp/restart.txt

  4. 好了,這樣就好了 ...

compass-rails Github README 上提到

if you are using the rails configuration files you should add:
config.compass.require "susy"
to your application.rb configuration file.

這段可以忽略,你只要到需要用到 susy 的檔案內引入 @import "susy.base"; 就可以了

然後也可以自己建立一個 _susy.base.css.scss 然後檔案內容:

@import "susy";
@import "sassy-buttons";

$total-columns: 12;
$column-width: 4em;
$gutter-width: 1em;
$grid-padding: $gutter-width;

就可以設定好了,不需要另外加上什麼奇怪的設定。

這樣應該就可以 work 了 ... 搞好久 @@

在 Ubuntu 上用 Ruby 寫一個縮圖工具

小小OS: 今天玩完後發現好好玩 XD ...

為了某個 Project 所以特別研究了一下步驟,這邊稍微做一下筆記。

這邊我會用 ImageMagick 當主要的縮圖工具,所以首先,我們不要使用 Ubuntu 自己的 ImageMagick ,而是直接上 ImageMagick 的官方網站下載最新版的來編譯,下載好後執行底下的指令再進行解壓縮原始碼的動作 (記得用 sudo or root 身份處理):

  1. apt-get remove imagemagick
  2. apt-get install libmagickcore-dev libmagickwand-dev

處理好後就可以開始解壓縮,然後用

  • ./configure
  • make
  • make install

來安裝 ImageMagick,並且在裝好後編輯 ~/.bash_profile 然後寫上 export LD_LIBRARY_PATH=/usr/local/lib ,這樣就可以了,退出 Shell 後重新登入就準備好了。

接下來,我們需要安裝 mini_magick 這個 Gem ... 不得不說這個東西真的超級好用 XD

你可以用 gem i mini_magick 安裝它,然後剩下的就是讀文件 http://rubydoc.info/github/minimagick/minimagick 就可以用了 XD

來寫一個圖片下載器好了 ... 下載好後可以縮成 800, 600, 400 三個尺寸的圖片

下載圖片

下載圖片可以透過 open-uri 這個 library 來處理,然後用

File.write(file_path, open(image_url).read, { mode: 'wb' })

就可以搞定,然後下載下來的圖片可以再用另外的工具去處理命名 ... 像是可以使用 SecureRandom.hex(15) 產生 30 個字的長度的亂數字串來產生 basename

改變圖片大小

透過 MiniMagick 我們可以很簡單的針對圖片進行一些處理,尤其是像是等比例縮放這種事情更是難不倒它!現在我們有個範例是我們會有三個不同寬度的尺寸準備用來轉換,所以我們可以先這樣做

image_sizes = [800, 600, 400]

然後寫一個變更圖片寬度的函式:

def resize(image_path, new_size)
  image = MiniMagick::Image.open image_path
  image.resize new_size
end

這樣只要透過 resize(image_path, 600) 就可以回傳一個被 resize 為寬度 600 的 image 物件,這時候可以透過 image.write(target_path) 就可以把圖片輸出到 target_path 去。

輸出不同尺寸圖片的檔案名稱

但是輸出圖片的時候我們需要有一個新的檔名,最好是 xxx_800.jpg 這種類型的名字,所以我們增加一個 function 來處理這件事。

def resize_name(image_path, size)
  ext_name = File.extname(image_path)
  filename = File.basename(image_path, ext_name)
  "#{filename}_#{size}#{ext_name}"
end

如此一來,我們可以用 resize_name("/tmp/helloworld.jpg", 300) 產生 /tmp/helloworld_300.jpg 這樣的名字了。

輸出圖片

在這邊我們改寫一下 resize function

def resize(image_path, new_size)
  image = MiniMagick::Image.open image_path
  image.resize new_size
  new_filename = resize_name(image_path, new_size)
  target_path = File.dirname(image_path)
  image.write File.join(target_path, new_filename)
end

這樣改寫後,就可以把圖片產生出尺寸後塞回原本的路徑底下,所以假設圖片原本是在 /tmp/helloworld.jpg 的話,我改成寬度 600px 就會產生到 /tmp/helloworld_600.jpg

針對多個尺寸進行轉換

這邊其實就很簡單,我們有 image_sizes 這個變數可以用,所以你可以在外面跑迭代或者把陣列傳到 resize 裡面去處理,這邊拿外部迭代做範例

image_path = "/tmp/helloworld.jpg"
image_sizes.each do |size|
  resize(image_path, size)
end

這樣就搞定了。

完整程式碼

def resize_name(image_path, size)
  ext_name = File.extname(image_path)
  filename = File.basename(image_path, ext_name)
  "#{filename}_#{size}#{ext_name}"
end

def resize(image_path, new_size)
  image = MiniMagick::Image.open image_path
  image.resize new_size
  new_filename = resize_name(image_path, new_size)
  target_path = File.dirname(image_path)
  image.write File.join(target_path, new_filename)
end

image_sizes = [800, 600, 400]
image_path = "/tmp/helloworld.jpg"
image_sizes.each do |size|
  resize(image_path, size)
end

大功告成

參考資料

plupload + carrierwave 實作筆記 (二)

真的就只是個小筆記而已 ... 這邊的 code 我寫得很髒,所以就不直接貼了,大概講一下做法。

第一步: 先幹出一個 AssetsController 負責接圖片

def create
  ea = EventImage.new
  ea.path = params[:file]
  ea.save

  render json: ea
end

第二步:

plupload 那邊基本上要自己幹一個上傳器出來,然後監聽 FileUploaded 事件,這個事件會傳三個參數回來,分別是: up, file, info 三個,第一個 up 應該就是 uploader 本身,第二個 file 是你上傳上去的那個 file ,而 info 包含了回傳的內容,其中 response 是純字串,如果你的 Server 會吐 JSON 回來,記得這邊上一下 JSON.parse 後才能用

補充記錄:

  1. 如果要做什麼檢查的話,譬如數量,可以用 up.files 去取得設定過上傳的檔案的陣列
  2. 可以用 up.removeFile(up.files[index]) 去刪除某個檔案
  3. 如果要選擇檔案後就可以上傳,那可以把 up.start(); 加在 FilesAdded 事件上
  4. 在透過 new plupload.Uploader() 建立上傳器的時候可以透過指定 browse_button 來選擇要觸發上傳功能的按鈕,然後就是其實我不知道 container 到底幹啥用的 ....

plupload-rails with carrierwave -- 實作筆記

一樣為了專案啊 ... (泣

為了練習英文,我試試看用英文寫筆記好了

Installing plupload-rails

  1. place gem 'plupload-rails' into your Gemfile and execute bundle install in your Terminal.app
  2. add following lines into your application.js and application.css
    • 'application.js'
    • //= require moxie
    • //= require plupload.dev
    • //= require plupload/i18n/de - for i18n ... maybe it has zh version :P
    • //= require plupload.settings - optional, but recommended ...
    • //= require jquery.plupload.queue - if you want to integrated with jQuery
    • 'application.css'
    • *= require jquery.plupload.queue
  3. Place following code on any view files you want.
<script>
  $(function(){
    $("#uploader").pluploadQueue({
      runtimes: 'html5,flash,silverlight',
      url: '<%= assets_path %>',
      multipart_params: {
        '<%= request_forgery_protection_token %>': '<%= form_authenticity_token %>',
        '<%= Rails.application.config.session_options[:key] %>': '<%= request.session_options[:id] %>'
      }
    });
  });
</script>

Okay ... that's it!

Controller / Model

I want to use the Carrierwave as my uploader, so first of all, I need to install it and make an uploader and I call it ImageUploader with Asset model.

So, I need to combine Asset model and ImageUploader together with path column, so in my asset.rb ...

class Asset < ActiveRecord::Base
  mount_uploader :path, ImageUploader
end

That's it!

And now, it's Controller's turn.

I have a controller called AssetsController and it has an action called create, that's do some magic in that action:

class AssetsController < ApplicationController

  def create
    asset = Asset.new(path: params[:file])
    result = asset.save
    
    render json: { result: result }
  end
  
end

okay ... that's it. If you want to have an association with User or Event ... etc, just feel free to add them, and add xxx_id in the JavaScript multipart_params settings, for example:

I want those images that I uploaded associated with current_user, I can make multipart_params like that:

multipart_params: {
        '<%= request_forgery_protection_token %>': '<%= form_authenticity_token %>',
        '<%= Rails.application.config.session_options[:key] %>': '<%= request.session_options[:id] %>',
        'user_id': <%= current_user.id =>
      }

See? So easy! Or you can do some magic with your url field, like url: '<%= event_images_path(@event) %>'

Okay ... That's it!

Learn more on https://github.com/gucki/plupload-rails