今週は僕の開発最終週だったので、仕上げを中心にやりました。グループで個々が機能を開発して、それをマージして一つのアプリとしてちゃんと動くのを見るとやっぱテンション上がりますね!
スタイリング
マージするとやっぱりスタイリングが崩れるところがどうしても出てくると思うんですね。Bootstrapを入れてたブランチと入れてないブランチをマージしたりするとBootstrapが悪さしたりとか。cssファイルをimportする順番のせいで上書きされちゃったりとか。そこの調整をしました。
主にサイドバーなんですが、一つは現在いるページへのボタン背景を変えました。
jQueryで今ユーザーが見ているページを取得して、それとリンク先が合致すればクラスを追加してます。こんな感じですね。
$(function(){
$('.gnavi_item a').each(function(){
var $href = $(this).attr('href');
if(location.href.match($href)) {
$(this).addClass('is_current');
} else {
$(this).removeClass('is_current');
}
});
});
その他もろもろきれいにしました。かなり細かい部分ばっかりなんで省略します。
実際に誰かにアプリを見せるときにユーザーが全然いなかったらさみしいですよね。なのでダミーユーザーを30人前後準備することになりました。
手動で一人一人フォームから登録していくこともできますが、エンジニアを称する人間がそんな人海戦術を是とするなんて言語道断だという結論になったので、スクレイピングで女性の画像を引っ張ってきてseedでデータベースに入れていくことにしました。
いや、ちゃんとやりましたよ…?
だいぶ前にカリキュラムで書いたコードを改変して使いました。今回はメイン画像を一枚、サブ画像を二枚取得します。取得先は女優さんがたくさん一覧で出ているページです。女優一覧ページの女優名にリンクが貼ってあり、そのリンク先にその女優の画像がぶわっと並んでる感じです。
require "mechanize"
def image_page_urls
agent = Mechanize.new
links = []
current_page = agent.get("取りたい画像があるURL")
elements = current_page.search('.image_list .imageBox a')
elements.first(40).each do |ele|
links << ele.get_attribute('href')
end
links.each_with_index do |link, i|
get_image('取りたい画像があるhost' + link, i)
end
end
def get_image(link, i)
agent = Mechanize.new
page = agent.get(link)
begin
main_image = page.search('#1_img')
agent.get(main_image.first.attributes["src"]).save "/Users/kosaburokaneko/projects/techexpert/pairs_clone/app/assets/images/avatar/user#{i+1}.jpg"
rescue
return
end
begin
sub_image1 = page.search("#{i+2}_img")
agent.get(sub_image1.first.attributes["src"]).save "/Users/kosaburokaneko/projects/techexpert/pairs_clone/app/assets/images/avatar/user#{i+1}_sub1.jpg"
rescue
begin
sub_image1 = page.search("#{i+3}_img")
agent.get(sub_image1.first.attributes["src"]).save "/Users/kosaburokaneko/projects/techexpert/pairs_clone/app/assets/images/avatar/user#{i+1}_sub1.jpg"
rescue
begin
sub_image1 = page.search("#{i+4}_img")
agent.get(sub_image1.first.attributes["src"]).save "/Users/kosaburokaneko/projects/techexpert/pairs_clone/app/assets/images/avatar/user#{i+1}_sub1.jpg"
rescue
puts "取得できませんでした"
end
end
end
begin
sub_image2 = page.search("#p1_#{i+5}_img")
agent.get(sub_image2.first.attributes["src"]).save "/Users/kosaburokaneko/projects/techexpert/pairs_clone/app/assets/images/avatar/user#{i+1}_sub2.jpg"
rescue
begin
sub_image2 = page.search("#p1_#{i+6}_img")
agent.get(sub_image2.first.attributes["src"]).save "/Users/kosaburokaneko/projects/techexpert/pairs_clone/app/assets/images/avatar/user#{i+1}_sub2.jpg"
rescue
begin
sub_image2 = page.search("#p1_#{i+7}_img")
agent.get(sub_image2.first.attributes["src"]).save "/Users/kosaburokaneko/projects/techexpert/pairs_clone/app/assets/images/avatar/user#{i+1}_sub2.jpg"
rescue
puts "取得できませんでした"
end
end
end
end
image_page_urls
なんでこんなbeginとrescueがこんなことになってるかというと、画像があったりなかったりするページだったので画像を取得できない可能性があったんですね。なのでもしメイン画像が取得できなかったらその女優は諦めて次の女優に移るというようにしてます。サブ画像については取得できなかったら次の画像を取りに行って、それを二回頑張って無理だったら諦めるという風にしてます。
あと取得画像の制限ももっと上手な方法があると思うんだよなあ…スクレイピングはほぼやったことがないんだけど、やっぱり取得成功してデータがもりもり増えるの見てるとなんか興奮するからもっと勉強したい。
で、取得できた画像はそれぞれ
- メイン画像: user_1.jpg
- サブ画像1: user_1_sub1
- サブ画像2: user_1_sub2
- メイン画像: user_2.jpg
- サブ画像1: user_2_sub1
- サブ画像2: user_2_sub2
という風にユーザー別に保存するようにしました。最近each_with_indexが大活躍してます。
保存した画像はcarrier_waveを使って保存する必要があって、それをユーザーと紐づかせなければいけません。なのでseed.rbには以下のように書きました。
32.times do
password = Faker::Internet.password(8)
User.create(
name: Faker::Japanese::Name.last_name,
gender: 2,
email: Faker::Internet.free_email,
password: password,
birthday: Faker::Time.between(50.years.ago, 20.years.ago, :all).to_s[0, 10],
nationality_id: 48,
narrow_address_id: rand(1..48),
)
end
32.times do |i|
CapturedImage.create(
content: File.open(Rails.root + "app/assets/images/avatar/user#{i+1}.jpg"),
status: 0,
user_id: "#{i+1}".to_i,
)
CapturedImage.create(
content: File.open(Rails.root + "app/assets/images/avatar/user#{i+1}_sub1.jpg"),
status: 1,
user_id: "#{i+1}".to_i,
)
CapturedImage.create(
content: File.open(Rails.root + "app/assets/images/avatar/user#{i+1}_sub2.jpg"),
status: 1,
user_id: "#{i+1}".to_i,
)
end
Fakerで日本語使う方法がいまいちわからなかったので、ruby-faker-japaneseというgemで対応しました。それでユーザー登録に必要な情報をダミーで入れて32人作成してます。
下の段がcarrier_waveの部分ですが、contentの部分は先ほど保存した画像を開くように設定してます。ちなみにstatusが0はメイン画像で、1はサブ画像です。これでユーザーとユーザー画像がちゃんとひも付けされるようになりました。この二つのファイルがあれば何百人だろうが自動でできます。
終わり
というわけで、僕の役目は終わりました。あとはグループでこのアプリを発表するだけです。とうとうここまで来てしまいました。
グループでスクラム開発をできたこともそうですが、既存のサービスのクローンをつくるのはすごい勉強になりました。どういう技術が実際に使われてるのかとか、CSSの細かなテクニックとか、自分で開発するプロセスじゃなかなかたどり着けない、既存サービスを研究することで初めてわかったことがいくつもありました。
スクールのカリキュラムとして既存サービスをコピーするのか、オリジナルサービスをつくるのか、どちらがいいのかは難しいところだと思います。正直自分でやる前は「既存サービスのコピーなんて大した勉強になんないでしょ」と思ってましたが、全然そんなことありませんでした。むしろ今では一からサービスを作るよりも勉強になる部分がたくさんあると思うようになりました。
あまり経験がない中でオリジナルサービスを作ろうとするとどうしても技術的に背伸びしにくい気がするんですよね。技術的にがんばるというよりも、サービス全体として一つ作り上げる方に意識が向くというか。なので結果的に本当の自分の技術的ポテンシャルより一段落ちる気がしてます。
でも自分の個性とか出す場所としてはオリジナルサービスってすごくいいと思います。デザインにこだわってもいいし、アイディアで勝負もできるし。もちろん技術的にすごいサービスってとこを狙ってもいいですし。
でもいろいろ考えた上で、多くの人には既存サービスをコピーする方が転職には役立つんじゃないかと思います。転職目的では。大概WEBサービスのアイディアなんてすでに作られてるので、どうせそういうインパクト勝負ができないんだったらコピーした方が見た目もきれいだしいろんな話もできると思うんだよなあ。