【Rails3.2】uniqメソッドを使った際に、ActiveRecord::StatementInvalidが発生してしまう場合
Rails3.2から導入されたActiveRecord::Relation#uniq はとっても便利で、
records.select(:name).uniq
と書くだけで、ユニークなnameの一覧が取得できます!
(recordsは何かしらレコードの集合です。)
でも
records = Client.order(:address) : records.select(:name).uniq
と書くと、
ActiveRecord::StatementInvalid: PG::Error: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
というようなエラーを吐いてしまいます。
これは、selectしていないカラムに含まれていないカラム(この例ではaddress)でorderしようとしたために発生しています。
この例ではorderを消せば良い話ですが、
他のメソッドからorder済みの値が渡ってくる場合は困ってしまいます。(´・ω・`)
そんな際は、reorder()メソッドを使えば良いです。
records = Client.order(:address) : records.reorder(:name) #それまでのorderをなかったことにして、orderしなおす records.select(:name).uniq
以上により、selectに含まれないカラムに対するorderを消すことが出来、無事動くようになりました。
update_allメソッドって便利だなー
where()などで必要な複数レコードを抽出しておいて、一括で値変更できます。
(ActiveRecord::Relationのメソッドとして実装されてる)
いままでsql直書きしてたよ。。(´・ω・`)
その前は、eachをレコード分実行して値書き換えてたよ。よくないよね。。(´;ω;ω;`)
忘備録的にリファレンスマニュアルのサンプルを貼り付けます。
# Update all customers with the given attributes Customer.update_all :wants_email => true # Update all books with 'Rails' in their title Book.update_all "author = 'David'", "title LIKE '%Rails%'" # Update all avatars migrated more than a week ago Avatar.update_all ['migrated_at = ?', Time.now.utc], ['migrated_at > ?', 1.week.ago] # Update all books that match conditions, but limit it to 5 ordered by date Book.update_all "author = 'David'", "title LIKE '%Rails%'", :order => 'created_at', :limit => 5 # Conditions from the current relation also works Book.where('title LIKE ?', '%Rails%').update_all(:author => 'David') # The same idea applies to limit and order Book.where('title LIKE ?', '%Rails%').order(:created_at).limit(5).update_all(:author => 'David')
【Ruby】条件分岐をワンライナーで書く
def special_or_normal @current_user.special? ? "special" : "normal" end
special? がtrueならspecialを返却、そうでなければnormalを返却。
?で条件分岐して、 : で分割して列挙する。
以下のコードと同じ。
def special_or_normal if(true == @current_user.special?) "special" else "normal" end end
【Rails】rakeで使えるタスクを調べる
$ rake --tasks
【Rails3】開発中にRailsを再起動しないといけないときは?
RailsはDevelopmentの場合、ブラウザから要求があるたびにクラスを読み込み直してくれるので、Railsを再起動せずとも加えた修正が反映されます(*´ω`*)
でも、下記3ケースの場合は修正が反映されないので要注意です。
(1)config/* が書き換わった場合
(2)lib/* が書き換わった場合
(3)bundle install をした場合(Gemfile.lockが書き換わった場合)
ついつい忘れがちな人は、上記ファイルが書き換わったら自動で再起動してくれるguard_railsが便利かもしれないですね!
https://github.com/johnbintz/guard-rails
【Javascript】PhantomJSで簡単スクレイピング
http://code.google.com/p/phantomjs/
Javascriptで動作する「ヘッドレスブラウザ」
参考URL
http://d.hatena.ne.jp/karasuyamatengu/20110126/1296066287
これをスクレイピングに使ってみます。JQueryも使えて楽しい。
今日はこのPhantomJSを使って、【コマンドライン英和辞典】を作ってみます。
ではソースコード(Coffeescript):
JqPageが親クラスで、JQueryを使ってスクレイピングするための基本機能を提供します。
Alcという小クラスで、英和辞典のアルクさんをスクレイピングします。
#!/usr/bin/env phantomjs # input check if(phantom.args.length == 0) console.log('please set url.') phantom.exit() class JqPage constructor: (@url) -> #@alert(@url) @page = require('webpage').create() @page.open(@url, @onOpen) return this onOpen: (status) => if(status == 'success') #@alert('open success') @page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", @onLoad) else @alert('fail') return onLoad: () => #@alert('jquery loaded') phantom.exit() return alert: (str) -> console.log(str) return this class Alc extends JqPage constructor: (@query) -> @url = "http://eow.alc.co.jp/search?q=" + @query super(@url) onLoad: () => txt = @page.evaluate -> $("#resultsList > ul > li:first").text() @alert(txt) super() aa = new Alc(phantom.args[0])
このファイルをalc.coffee として保存し、
$ alc.coffee foo
と入力すると、、、
foo 【1名】=foo dog【2名】《コ》フー◆メタ構文変数名。◆【参考】metasyntactic variable ; foobar
出来たー(*´Д`*)
実質
$("#resultsList > ul > li:first").text()
という一行でデータを引っ張ってこれます。