2015-04-22 3 views
1

Я использую FatFreeFramework 3.4.0FatFreeFramework CopyFrom и обновить

Я использую класс Mapper (SQL) Я пытаюсь обновить строку непосредственно из POST, но используя CopyFrom(), а затем обновление не работает, как ожидалось И save() попытается вставить новую строку.

Вот пример обновления цены книги (использование изменило значение цен от 20 до 43):

Books Table 
id (PK)|price 
------------- 
2  |20 



<from> 
    book id: <input type="text" id="id" name="id" value="2" /> 
    price: <input type="text" id="price" name="price" value="43" /> 
</from> 


<?php 
function update_book_price(){ 
    $mapper->copyfrom('POST'); 
    $mapper->update(); 
} 

Это запрос, картограф продукция:

UPDATE book SET id = 2, price = '43' WHERE id = 0

И это то, что я ожидаю, что это будет:

UPDATE book SET id = 2, price = '43' WHERE id = 2

Я знаю, что я могу решить эту проблему с помощью функции загрузки(). Но мне не нужен двойной запрос. Я не эксперт в шаблоне Data mapper, поэтому исправьте меня, если я не понимаю, как это должно работать. Как я могу это решить?

+1

'цена: <входной тип = "text" id = "id" name = "id" value = "43" /> 'должно быть' цена: ' –

+0

Спасибо. Моя ошибка –

ответ

1

По определению, картограф должен быть сопоставлен с записью DB.

В F3:

  • вы называете load() отобразить запись
  • вы называете dry(), чтобы проверить, если действительная запись была сопоставляются (сухой = не отображается)

Так что в вашем case:

function update_book_price($f3){ 
    $mapper->load(array('id=?',$f3->get('POST.id'))); 
    if (!$mapper->dry()) { 
    $mapper->copyfrom('POST'); 
    $mapper->update(); 
    } 
} 

Значительная реализация всего этого было бы сопоставить URL для записи:

$f3->map('/book/@id','Book'); 

Тогда в Book классе, вы бы проверить, если @id действует до выполнения какого-либо кода контроллера:

class Book { 

    protected $mapper; 

    function get($f3) { 
    //show book 
    } 

    function put($f3) { 
    //update book 
    $this->mapper->copyfrom('POST'); 
    $this->mapper->save(); 
    } 

    function beforeRoute($f3,$params) { 
    $this->mapper=new DB\SQL\Mapper(..); 
    $this->mapper->load(array('id=?',$params['id'])); 
    if ($this->mapper->dry()) 
     $f3->error(404);//invalid id => book not found 
    } 

} 
+0

Спасибо за подробный ответ. Поэтому, если я хочу обновить строку одним запросом, я должен использовать «Обычный» SQL? –

+0

Что значит «один запрос»? В примере, описанном выше, '$ this-> mapper-> save()' будет выполнять один оператор 'UPDATE'. – xfra35

+0

Но прежде чем я смогу mapper-> save(), я должен сначала mapper-> load() и это 2 запроса. Но с обычным SQL я могу просто: ОБНОВИТЬ книги SET price = 43 WHERE id = 2 и эта одиночная набережная. (Скажем, мне не нужно сначала проверять, существует ли книга) –