3

次の問題の設計提案をお願いします。

Codeigniter/Grocery_CRUDを使用しています。

私のシステムは、同じクライアント内にマルチテナント(異なる自律サイト)があります。一意の論理キーを持つテーブルのインスタンスがかなりあります。そのようなテーブル構造の1つは次のとおりです。

equip_items
id(pk)
equip_type_id(fkからequip_types)
site_id(fkからサイト)
name

ここで、(equip_type_id、site_id、name)は、私のデータベース内の一意のキーです。

問題は、grocery_CRUDフォームを使用して、このデータベースルールに違反するレコードを追加または編集する場合、追加または編集は失敗しますが(dbの制約のため)、フィードバックが得られないことです。

is_unique form_validationルールのバリエーションが必要です。これにより、一意である必要があるフィールド*s*を指定できます。

問題:
ルールを指定する方法は?set_rules()は特定のフィールド用であり、ルールが適用される複数のフィールドがあります。それは、Form_validationパターンを放棄する必要があるという意味ですか?または、「一致」ルールパターンに従い、他のフィールドをポイントしますか?

おそらくコールバック関数の方が良いでしょうが、これは私が最後にこの問題を抱えている各モデルでカスタム関数を書くことを意味しますこれは9つのテーブルです。これを1か所で行う方がはるかに良いようです(form_validationを拡張します)。

この問題をすでに解決しているcodeigniterまたはgrocery_CRUDにすでに何かが欠けていますか?

あなたが持っているかもしれないどんな提案/アドバイスもいただければ幸いです。

編集: 実際には、ジョニーが提供したソリューションは完全には成功していないようです-それはunique_fields()の各フィールドが独立して一意であることを強制します-それぞれにis_unique()を設定するのと同じです。私の問題は、私のシナリオでは、これらのフィールドが複合一意キー(ただし主キーではない)であるということです。それが重要かどうかはわかりませんが、元の問題の説明に加えて、次のようになります。1)site_idは「非表示」のfield_typeです-ユーザーが別のサイトにいることを心配したくないので、site_idを処理していますシーン。2)equip_status_id属性(一意キーの一部ではない)についても同じように扱います。そして3)私はこれらすべての外部キー属性にset_relations()を持っており、grocery_CRUDは親切にも私のために素晴らしいドロップダウンを処理します。

編集2 私はコールバックを使用してこれを解決しました。

4

2 に答える 2

11

更新:このコードは現在、食料品のCRUDバージョン> = 1.4の一部であり、拡張機能を使用する必要はありません。詳細については、unique_fieldsのドキュメントを参照してください

私はそれをできるだけ簡単に説明しようとします:

1.まず、食料品のCRUDが1.3.3以下の場合は、次の小さな変更を使用する必要があります:https ://github.com/scoumbourdis/grocery-crud/commit/96ddc991a6ae500ba62303a321be42d75fb82cb2

2.次に、application/librariesにgrocery_crud_extended.phpという名前のファイルを作成します

3.ファイルapplication/libraries/grocery_crud_extended.phpで以下のコードをコピーします

<?php 
class grocery_CRUD_extended extends grocery_CRUD
{
    protected $_unique_fields = array();

    public function unique_fields()
    {
        $args = func_get_args();

        if(isset($args[0]) && is_array($args[0]))
        {
            $args = $args[0];
        }

        $this->_unique_fields = $args;

        return $this;
    }

    protected function db_insert_validation()
    {
        $validation_result = (object)array('success'=>false);

        $field_types = $this->get_field_types();
        $unique_fields = $this->_unique_fields;
        $add_fields = $this->get_add_fields();

        if(!empty($unique_fields))
        {
            $form_validation = $this->form_validation();

            foreach($add_fields as $add_field)
            {
                $field_name = $add_field->field_name;
                if(in_array( $field_name, $unique_fields) )
                {
                    $form_validation->set_rules( $field_name, 
                            $field_types[$field_name]->display_as, 
                            'is_unique['.$this->basic_db_table.'.'.$field_name.']');
                }
            }

            if(!$form_validation->run())
            {
                $validation_result->error_message = $form_validation->error_string();
                $validation_result->error_fields = $form_validation->_error_array;

                return $validation_result;
            }
        }
        return parent::db_insert_validation();
    }

    protected function db_update_validation()
    {
        $validation_result = (object)array('success'=>false);

        $field_types = $this->get_field_types();
        $unique_fields = $this->_unique_fields;
        $add_fields = $this->get_add_fields();

        if(!empty($unique_fields))
        {
            $form_validation = $this->form_validation();

            $form_validation_check = false;

            foreach($add_fields as $add_field)
            {
                $field_name = $add_field->field_name;
                if(in_array( $field_name, $unique_fields) )
                {
                    $state_info = $this->getStateInfo();
                    $primary_key = $this->get_primary_key();
                    $field_name_value = $_POST[$field_name];

                    $ci = &get_instance();
                    $previous_field_name_value = 
                        $ci->db->where($primary_key,$state_info->primary_key)
                            ->get($this->basic_db_table)->row()->$field_name;

                    if(!empty($previous_field_name_value) && $previous_field_name_value != $field_name_value) {
                        $form_validation->set_rules( $field_name, 
                                $field_types[$field_name]->display_as, 
                                'is_unique['.$this->basic_db_table.'.'.$field_name.']');

                        $form_validation_check = true;
                    }
                }
            }

            if($form_validation_check && !$form_validation->run())
            {
                $validation_result->error_message = $form_validation->error_string();
                $validation_result->error_fields = $form_validation->_error_array;

                return $validation_result;
            }
        }
        return parent::db_update_validation();
    }   

}

4.これで、次のようにgrocery_CRUD_extendedをロードする必要があります。

    $this->load->library('grocery_CRUD');
    $this->load->library('grocery_CRUD_extended');

次に、以下を使用します。

$crud = new grocery_CRUD_extended();

それ以外の:

$crud = new grocery_CRUD();

5.これで、次のように機能するunique_fieldsを簡単に作成できます。

$crud->unique_fields('field_name1','field_name2','field_name3');

あなたの場合:

$crud->unique_fields('equip_type_id','site_id');

とても簡単ですよね?

これは、食料品のCRUDのコアを実際に変更せずに、フィールドが一意であるかどうかをチェックしています。grocery_CRUDの代わりにgrocery_CRUD_extendedを使用して、通常どおり食料品のCRUDライブラリを更新できます。私はライブラリの作成者なので、これを食料品のCRUDバージョン1.4に含めようとします。したがって、将来、grocery_CRUD_extendedを使用する必要はありません。

于 2012-11-25T00:50:06.463 に答える
3

私はコールバックを使用してこれを行いました:

$crud->set_rules('name','Name','callback_unique_equip_item_check['.$this->uri->segment(4).']');     

function unique_equip_item_check($str, $edited_id)
{
    $var = $this->Equip_Item_model->is_unique_except(
            $edited_id,
            $this->input->post('site_id'),
            $this->input->post('equip_type_id'),
            $this->input->post('name'));

    if ($var == FALSE) {
        $s = 'You already have an equipment item of this type with this name.';
        $this->form_validation->set_message('unique_equip_item_check', $s);
        return FALSE;
        }
    return TRUE;
}
于 2012-12-10T00:39:54.030 に答える