4

私はRailsアプリケーションでActiveRecordを使用したいと思いますが、ActiveRecordモデルの代わりにPostgreSQLデータベースにデータ制約をエンコードしたいと思います。例えばActiveRecord + postgresql + data constraints

、私は足場によって生成されたモデル、私は名前が合理的に長くすることを確認するだろう

rails generate scaffold User name:string email:string yearofbirth:integer 

を持っている場合。例えば

class User < ActiveRecord::Base 
    validates :name, :length => { :maximum => 140 } 
    validates_uniqueness_of :name 
    validates_numericality_of :yearofbirth, :greater_than_or_equal_to => 1900 
end 

これらの検証は、ActiveRecordが不正なデータを追加しようとすると、いくつかの素晴らしいエラーメッセージをビューに表示するため、有効です。

しかし、私はデータベース自体にルールをエンコードし、データベースにActiveRecordへの見栄えの有益なエラーメッセージを投げて、それをビューレイヤに渡してもらいたいと思います。たとえば、

create table "Users" (
    id integer unique, 
    name varchar(140) unique check(length(name)<140), 
    email varchar(255), 
    yearofbirth integer check (yearofbirth >= 1900) 
); 

これを行うには、私は何をする必要がありますか? pgAdmin IIIツールで試したところ、エラーメッセージが表示されましたが、カスタマイズしたいと思います。

また、これらのデータベースルールをRubyのデータベース移行ファイルにエンコードする方法はありますか?

私に教えていただけると助かります。

+3

1:データ上の制約は常にであるべきDBを作成し、ActiveRecordモデルに自動的に追加します。 RailsとActiveRecordは、唯一の唯一のチェックポイントではなく、私たちのデータにアクセスする唯一の方法です。これは完全性を保証し、ドライ原則を尊重します。したがって、あなたの質問は面白く、良い答えもあります。 – lkuty

答えて

1

上記のCREATE TABLEステートメントで唯一間違っているのは、USERが予約語であり、引用符で囲む必要があります。したがって、

CREATE TABLE "User" (...); 

となります。

+0

ありがとうございます。私は訂正をした。万一、制約違反からカスタムエラーメッセージを取得する方法を知っていますか? –

+0

特定のSQLSTATEエラー・コードを、クライアントまたはストアード・プロシージャーで捕捉できます。しかし、データベースシステムでエラーメッセージを直接変更する方法はありません。 –

1

実際にはテーブルユーザーが必要です。他のケースでは、さらに多くの問題が発生する可能性があります。 もちろん、他の変曲を定義することはできますが、それは単に間違っていて、レールウェイではありません。

class User 
    ... 
end 

その後、 がテーブルにユーザーを作成...ここ

1

は(Postgresqlのではない)のOracleを使用した例であるが、考え方は同じです。カタログのみが異なります。注意しなければならないのは、null制約のための制約 "table_column_nn"の名前です。以下の解決策はおそらく改善されるでしょう。

Authorを表すモデルAuthorがNULL名を持つべきでないとします。

class Author < ActiveRecord::Base 
    has_and_belongs_to_many :books 

    r = ActiveRecord::Base.connection.select_one("select CONSTRAINT_NAME from user_constraints where TABLE_NAME = 'AUTHORS' and constraint_name like '%_NN'") 
    m = r["constraint_name"].match(/^[^_]*_([^_]*)_NN$/) 
    if !m.nil? 
    column = m[1] 
    validates column.downcase.to_sym, :presence => true 
    end 
end 

セットアップにSQLスクリプトはスキーマは次のとおりです。

create table authors (
    id integer primary key, 
    name varchar2(100) constraint authors_name_nn not null, 
    updated_at timestamp with local time zone, 
    created_at timestamp with local time zone 
); 

DB上だけではSQL要求はこれを与える:

select constraint_name, search_condition from user_constraints where table_name = 'AUTHORS' and constraint_name like '%_NN'; 
CONSTRAINT_NAME  SEARCH_CONDITION 
---------------  ---------------------- 
AUTHORS_NAME_NN  "NOM" IS NOT NULL 

1 row selected. 
関連する問題