ruby on rails コマンド
コマンド
appnameを作成
rails new appname
cd appname
dbを作成
rake db:create
rails generate系でコマンドが応答しない時があるのでその時使用
spring stop
controllernameのcontorollerを作成その中でindexメソッドを作成する。
rails generate controller controllername index
modelnameのmodelを作成nameはフィールド名。idなどは作ってくれるので必要なし。
その後のdb:migrate必要
rails generate model modelname name:text
rails db:migrate
rails db:seed(seedを作ってる場合)
設計 掲示板作り
ruby on railsで何かポートフォリオを作ろうかと掲示板を作ろうかと思ったのですが、色々詰まったりしたので設計というか計画というかまぁそんな感じのものやっていきます。
基本的には4画面でトピック一覧ページ,トピック作成ページ,書き込み一覧ページ,書き込み作成ページ。
画面的機能で言うと、
トピック一覧ページ
トピック一覧表示(リンク付き)
新規トピック作成
ページネーション
トピック作成
トピック送信
書き込み一覧ページ
トピック名表示
書き込み一覧表示
新規書き込み作成
ページネーション
書き込み作成
トピック表示
書き込み送信
コードベースで考えると、
コントローラー
topic_controller indexメソッド→トピック一覧ページ
topic_controller createメソッド→トピック作成ページ
topic_controller postcreateメソッド→トピック作成ページ結果を送信
post_controller indexメソッド→書き込み一覧ページ
post_controller createメソッド→書き込み作成ページ
post_controller postcreateメソッド→書き込み作成ページ結果を送信
モデル
topic
id :id
title :タイトル
post
id :id
post_id:1トピック内でのid
topic_id:topicのid
name:投稿者名
content:投稿内容
creationday:作成日時
備考
railsだとモデル作成時に作成日時と更新日時が作られるのでcreationdayはいらない気がする。
C# リフレクション
C#のリフレクションを最近触ったので少し復習がてら記事にしてみました。
まずはクラスを用意。
class Fruits { public int Apple { get; set; } public string Banana { get; set; } public int? Cherry { get; set; } public int Drian { get; } = 3; public int Sum() { return Apple + int.Parse(Banana) + (int)Cherry + Drian; } }
GetPropertiesでプロパティの情報を取り出せる。例えば.Nameでフィールド名を取り出せる。
class Program { static void Main(string[] args) { var fruit = new Fruits(); foreach (var prop in fruit.GetType().GetProperties()) { Console.WriteLine(prop.Name); } } }
結果
Apple Banana Cherry Drian
.canWriteでsetterを持っているか判断する。
class Program { static void Main(string[] args) { var fruit = new Fruits(); foreach (var prop in fruit.GetType().GetProperties()) { Console.WriteLine(prop.Name + ":" + prop.CanWrite); } } }
結果
Apple:True Banana:True Cherry:True Drian:False
.PropertyNameでフィールドの型名が取り出せる。
class Program { static void Main(string[] args) { var fruit = new Fruits(); foreach (var prop in fruit.GetType().GetProperties()) { Console.WriteLine(prop.Name + ":" + prop.PropertyType); } } }
結果
Apple:System.Int32 Banana:System.String Cherry:System.Nullable`1[System.Int32] Drian:System.Int32
.SetValueメソッドでは値を入れることができる。
一つ目の引数は入れ物のオブジェクト。
二つ目の引数は入れ物に入れる値。
class Program { static void Main(string[] args) { var fruit = new Fruits(); var instance = new Fruits(); foreach (var prop in fruit.GetType().GetProperties()) { if (!prop.CanWrite) continue; if(prop.PropertyType == typeof(int)) { prop.SetValue(instance, 1); } else if(prop.PropertyType == typeof(int?)) { prop.SetValue(instance, 2); } else if(prop.PropertyType == typeof(string)) { prop.SetValue(instance, "3"); } } Console.WriteLine("Apple = " + instance.Apple); Console.WriteLine("Banana = " + instance.Banana); Console.WriteLine("Cherry = " + instance.Cherry); }
結果
Apple = 1 Banana = 3 Cherry = 2
.GetValueで引数に入っている値を取り出すことができる。
class Program { static void Main(string[] args) { var fruit = new Fruits(); var instance = new Fruits(); foreach (var prop in fruit.GetType().GetProperties()) { if (!prop.CanWrite) continue; if (prop.PropertyType == typeof(int)) { prop.SetValue(instance, 1); Console.WriteLine(prop.GetValue(instance)); } else if (prop.PropertyType == typeof(int?)) { prop.SetValue(instance, 2); Console.WriteLine(prop.GetValue(instance)); } else if (prop.PropertyType == typeof(string)) { prop.SetValue(instance, "3"); Console.WriteLine(prop.GetValue(instance)); } } } }
結果
1 3 2
他にも色々あるけど割とこの上記のものをよく使った。
C# Fileの読み書き
仕事で扱う機会があったのでこの機会に少しまとめてみようかな、と。
とりあえず基本的な事項のみで。
C#の現在のものだとopenとかcloseとかは気にしないですむ。
まずは普通にファイルの書き込み。
class Program { private static string path = "test.txt"; static void Main(string[] args) { File.WriteAllText(path, "HelloWorld"); } }
結果
HelloWorld
配列を入れてファイルの書き込みもできるらしい。
配列の要素ごとに改行を行う。
class Program { private static string path = "test.txt"; static void Main(string[] args) { var array = new string[] {"apple", "banana", "cherry"}; File.WriteAllLines(path, array); } }
結果
apple banana cherry
ファイルの読み込みも簡単に行える。
前提として上記のappleなどが書かれているファイルを読み込む。
class Program { private static string path = "test.txt"; static void Main(string[] args) { var reader = File.ReadAllText(path); Console.WriteLine(reader); } }
結果
apple banana cherry
上記のWriteLinesと似たような感じでReadAllLinesメソッドを使用すると、行ごとの配列で結果が返ってくる。
class Program { private static string path = "test.txt"; static void Main(string[] args) { var reader = File.ReadAllLines(path); foreach (var item in reader) { Console.WriteLine(item); } } }
結果
apple banana cherry
WriteLineのデメリットとして二回行ってしまうと結果が上書きされてしまう。
class Program { private static string path = "test2.txt"; static void Main(string[] args) { File.WriteAllText(path, "HelloWorld"); File.WriteAllText(path, "HelloWorld2"); } }
結果
HelloWorld2
なので、AppendAllTextを使う。
なお、AppendAllLinesは配列やリストで渡すと行ごとに書き込みを行ってくれる。
というか、これだけは配列じゃなくてもいいらしい。
class Program { private static string path = "test3.txt"; static void Main(string[] args) { File.AppendAllText(path, "HelloWorld"); File.AppendAllText(path, "HelloWorld2"); File.AppendAllLines(path, new string[] {"apple", "banana"}); File.AppendAllLines(path, new List<string>() {"cherry","drian"}); } }
結果
HelloWorldHelloWorld2apple banana cherry drian
C# Environment
C#でfileの書き込みをちらほらやってた時に、Environment.NewLineというのを見たので、どんなものがあるのか見てみた。
NewLineは改行を行う。PCごとに改行文字は異なるがそういうものを気にしなくてもすむ。
Console.WriteLine("AAA" + Environment.NewLine + "BBB");
結果
AAA BBB
MachineNameはmacだとmacではなくターミナルの名前の部分が表示された。
Console.WriteLine(Environment.MachineName);
結果
xxxxxxxxmacBook-Pro
OSVersionでOSのバージョンが取得できる。ただしToString()が必要。
OSVersion.ToString()
Console.WriteLine(Environment.OSVersion.ToString());
結果
Unix 18.6.0.0
スタックトレースの表示。
Console.WriteLine(Environment.StackTrace);
結果
at System.Environment.get_StackTrace() at Testapp2.Program.Main(String[] args) in /Users/******/Projects/Testapp2/Testapp2/Program.cs:line 16
見た所使いそうなのはこのあたり。
他にも、環境変数の取得や環境変数の設定などもすることができ
インストーラーを作ったりするのに使えそう。
コマンドライン関連のものもあったが使い道はあるのだろうか...
参考
Environment Class (System) | Microsoft Docs
C# ref修飾子, out修飾子
C#のout修飾子、ref修飾子はメソッド使用時に参照を渡すことを目的としている。
いくつか例を示す。
まずはクラスの準備。
class Student { public Student(int Id, string Name, int ScoreJapanese, int ScoreMath, int ScoreEnglish, int ClassNumber) { this.Id = Id; this.Name = Name; this.ScoreJapanese = ScoreJapanese; this.ScoreMath = ScoreMath; this.ScoreEnglish = ScoreEnglish; this.ClassNumber = ClassNumber; } public int Id { get; set; } public string Name { get; set; } public int ScoreJapanese { get; set; } public int ScoreMath { get; set; } public int ScoreEnglish { get; set; } public int ClassNumber { get; set; } }
次にStudent型のの変数を用意し、メソッドに入れてstudentのみ値を変える。
static void Main(string[] args) { var student = new Student(1, "taro", 82, 71, 75, 1); Console.WriteLine(student.Name + ":" + student.Id); classSub(student); Console.WriteLine(student.Name + ":" + student.Id); } public static void classSub(Student student) { student.Id = 2; }
結果はstudentのidは2に変わる。
このようにメソッドに値を渡し、その値を変更した時元の値にも
影響を及ぼすことを参照渡しという。
通常の引数となると、値は変わることはない。
例えば次のような例であればstudentの値は変わらない。
static void Main(string[] args) { var student = new Student(1, "taro", 82, 71, 75, 1); Console.WriteLine(student.Name + ":" + student.Id); classSub2(student); Console.WriteLine(student.Name + ":" + student.Id); } public static void classSub2(Student student) { student = new Student(2, "taro", 82, 71, 75, 1); }
ここで無理やり参照渡しにするのがout修飾子とref修飾子だ。
以下のように使う。
ref修飾子。
static void Main(string[] args) { var student = new Student(1, "taro", 82, 71, 75, 1); Console.WriteLine(student.Name + ":" + student.Id); refSub1(ref student); Console.WriteLine(student.Name + ":" + student.Id); } public static void refSub1(ref Student student) { student = new Student(2, "taro", 82, 71, 75, 1); }
out修飾子
static void Main(string[] args) { var student = new Student(1, "taro", 82, 71, 75, 1); Console.WriteLine(student.Name + ":" + student.Id); outSub1(out student); Console.WriteLine(student.Name + ":" + student.Id); } public static void outSub1(out Student student) { student = new Student(2, "taro", 82, 71, 75, 1); }
違いは大してないような気がするがoutSub1で使ってるoutのついてる引数は
メソッド内で何かしらの値を割り当てられることが必要。
と、ここまで説明してきたけど、正直あまり使わない方がいいような修飾子ではある。
ただし、これを使ってるint.TryParseメソッドやDictionary.TryGetValueメソッドというものがあるので
ある程度は知っておいた方がいいかな、と。
int.TryParseメソッド
int.TryParse("123", out var number); Console.WriteLine(number);
パースとはもちろんキャストのことだがこの場合はstringの123をintに変換する。
さらに第2引数にoutを入れることによってnumberという変数を宣言しつつ123をキャストした結果を格納できる。
キャストに成功すれば、Trueを返し失敗すれば Falseを返す。
Dictionary.TryGetvalueメソッド
dict.Add("田中", "たなか"); Console.WriteLine(dict.TryGetValue("鈴木", out var value)); Console.WriteLine(value); Console.WriteLine(dict.TryGetValue("田中", out var value2)); Console.WriteLine(value2);
C#のDictionary型はkeyが存在しない場合例外が発生してしまう。
なので、TryGetValueによってkeyがあるか確かめつつ値を確認することが重要。
これも上のTryParseメソッドと同様にkeyがあるかを確認し、あった場合はvalueに格納。
さらに値があった場合はTrueを返す。なければFalseを返す。
C# Linq
C#のLinqとはListの操作をSQLライクに書けるようにしたもの。
メソッドの書き方とキーワードを使う書き方の二つがあるが、今回はメソッドを使ったやり方を書く。
まずは準備としてクラスを用意する。
class Student { public Student(int Id, string Name, int ScoreJapanese, int ScoreMath, int ScoreEnglish, int ClassNumber) { this.Id = Id; this.Name = Name; this.ScoreJapanese = ScoreJapanese; this.ScoreMath = ScoreMath; this.ScoreEnglish = ScoreEnglish; this.ClassNumber = ClassNumber; } public int Id { get; set; } public string Name { get; set; } public int ScoreJapanese { get; set; } public int ScoreMath { get; set; } public int ScoreEnglish { get; set; } public int ClassNumber { get; set; } }
次にリストに入れるデータの用意。
最後の一行がリンクを使うための準備である。
static void main(string[] args) { var Students = new List<Student>(); //ID,名前,国語の点数,数学の点数,英語の点数,クラス Students.Add(new Student(1, "taro", 92, 83, 81, 1)); Students.Add(new Student(2, "hanako", 85, 38, 97, 1)); Students.Add(new Student(3, "ryo", 92, 91, 95, 1)); Students.Add(new Student(4, "ichiro", 61, 72, 45, 2)); Students.Add(new Student(5, "runa", 52, 91, 38, 2)); Students.Add(new Student(6, "akira", 82, 85, 77, 2)); Students.Add(new Student(7, "yuka", 97, 24, 51, 3)); Students.Add(new Student(8, "yoshiki", 51, 92, 73, 3)); Students.Add(new Student(9, "arisa", 62, 73, 75, 3)); IEnumerable<Student> Linq = Students; }
Selectメソッド。
mainメソッドの最後に追加
実行すると、*名前*のように表示される。
foreach (var student in Linq.Select(x => "*" + x.Name + "*")) { Console.WriteLine(student); }
Whereメソッド
mainメソッドの最後に追加
実行するとIDが偶数のものが表示される。
foreach (var student in Linq.Where(x => x.Id % 2 == 0)) { Console.WriteLine(student.Name); }
上記2つを組み合わせたWhereメソッドとSelectメソッド
mainメソッドの最後に追加。
実行するとIDが偶数のものが*名前*の形式で表示される。
foreach (var student in Linq.Where(x => x.Id % 2 == 0).Select(x => "*" + x.Name + "*")) { Console.WriteLine(student); }
OrderByメソッド
mainメソッドの最後に追加
実行すると順番が指定したものの昇順に並びかわる。
foreach (var student in Linq.OrderBy(x => x.ScoreJapanese)) { Console.WriteLine(student.Name + ":" + student.ScoreJapanese); }
OrderByDescendingメソッド
mainメソッドの最後に追加
実行すると順番が指定したものの降順に並びかわる。
foreach (var student in Linq.OrderByDescending(x => x.ScoreJapanese)) { Console.WriteLine(student.Name + ":" + student.ScoreJapanese); }
ThenByメソッド
並び替えを2回行う場合にはOrderByを2回使うのではなく2回目はThenByを使う。
mainメソッドの最後に追加。
実行すると順番がOrderByDescendingで指定したものの降順かつ
ThenByDescendingで指定したものの降順で並びかわる。
foreach (var student in Linq.OrderByDescending(x => x.ClassNumber).ThenByDescending(x => x.ScoreEnglish)) { Console.WriteLine(student.Name + ":" + student.ClassNumber + ":" + student.ScoreEnglish); }
最後に全体を表示。
using System; using System.Collections.Generic; using System.Linq; namespace TestApp1 { class Program { static void Main(string[] args) { Console.WriteLine("start"); var Students = new List<Student>(); Students.Add(new Student(1, "taro", 92, 83, 81, 1)); Students.Add(new Student(2, "hanako", 85, 38, 97, 1)); Students.Add(new Student(3, "ryo", 92, 91, 95, 1)); Students.Add(new Student(4, "ichiro", 61, 72, 45, 2)); Students.Add(new Student(5, "runa", 52, 91, 38, 2)); Students.Add(new Student(6, "akira", 82, 85, 77, 2)); Students.Add(new Student(7, "yuka", 97, 24, 51, 3)); Students.Add(new Student(8, "yoshiki", 51, 92, 73, 3)); Students.Add(new Student(9, "arisa", 62, 73, 75, 3)); IEnumerable<Student> Linq = Students; //select foreach (var student in Linq.Select(x => "*" + x.Name + "*")) { Console.WriteLine(student); } //where foreach (var student in Linq.Where(x => x.Id % 2 == 0)) { Console.WriteLine(student.Name); } //whereとselect foreach (var student in Linq.Where(x => x.Id % 2 == 0).Select(x => "*" + x.Name + "*")) { Console.WriteLine(student); } //orderby foreach (var student in Linq.OrderBy(x => x.ScoreJapanese)) { Console.WriteLine(student.Name + ":" + student.ScoreJapanese); } //orderbyDescending foreach (var student in Linq.OrderByDescending(x => x.ScoreJapanese)) { Console.WriteLine(student.Name + ":" + student.ScoreJapanese); } //ThenByDecending foreach (var student in Linq.OrderByDescending(x => x.ClassNumber).ThenByDescending(x => x.ScoreEnglish)) { Console.WriteLine(student.Name + ":" + student.ClassNumber + ":" + student.ScoreEnglish); } } } class Student { public Student(int Id, string Name, int ScoreJapanese, int ScoreMath, int ScoreEnglish, int ClassNumber) { this.Id = Id; this.Name = Name; this.ScoreJapanese = ScoreJapanese; this.ScoreMath = ScoreMath; this.ScoreEnglish = ScoreEnglish; this.ClassNumber = ClassNumber; } public int Id { get; set; } public string Name { get; set; } public int ScoreJapanese { get; set; } public int ScoreMath { get; set; } public int ScoreEnglish { get; set; } public int ClassNumber { get; set; } } }