Welcome Guest, Not a member yet? Register   Sign In
Edit vs update
#1

[eluser]JonoB[/eluser]
Hi all,

I am (almost) brand new to MVC frameworks, and I'm just trying to get my head around the best way to handle edits and updates. I've set up a simple test to CRUD a database. The one part that I am not 100% sure is how I have handled the edit and update logic.

I am using www.phpactiverecord.org as my ORM, as I am familiar with it from another project. I may switch over to CI ActiveRecord lib in due course.

I kinda cobbled this code from the help docs - its part of the products controller. Basically, the edit function and view lets me look at a single product. Clicking submit calls the update function, which runs through the validation rules. If validation passes, then we update the database and redirect to the product listing. If validation fails, then we redirect back to the edit view so that the user can try again.

Code:
function edit($id = '')
{
    if ($id)
    {
        $data['product'] = product_model::find($id)->to_array();
        $data['message'] = '';
    }
    else
    {
        $data['message'] = 'No product found';
    }
    
    $data['title'] = 'Edit Product';
    $data['action'] = site_url('products/update');
    $data['link_back'] = anchor('products', 'Back to list of products', array('class' => 'back'));

    $this->load->view('products/edit', $data);
}

function update()
{
    // set validation properties
    $this->form_validation->set_rules('code','Product Code','required|max_length[10]');
    $this->form_validation->set_rules('qty_sales','Sales Qty','numeric');
    $this->form_validation->set_rules('qty_purchases','Purchases Qty','numeric');
    $this->form_validation->set_rules('description','Description','max_length[255]');
    $this->form_validation->set_rules('unit_sales','Unit Sales','numeric');
    $this->form_validation->set_rules('unit_purchases','Unit Purchases','numeric');

    $this->form_validation->set_error_delimiters('<br /><span class="error">', '</span>');

    $data = array(
        'id' =>             $this->input->post('id'),
        'code' =>           $this->input->post('code'),
        'description' =>    $this->input->post('description'),
        'qty_sales' =>      $this->input->post('qty_sales'),
        'qty_purchases' =>  $this->input->post('qty_purchases'),
        'unit_sales' =>     $this->input->post('unit_sales'),
        'unit_purchases' => $this->input->post('unit_purchases'));

    // run validation
    if ($this->form_validation->run() == FALSE)
    {
        $ret['title'] = 'Edit Product';
        $ret['action'] = site_url('products/update');
        $ret['link_back'] = anchor('products', 'Back to list of products', array('class' => 'back'));
        $ret['message'] = '';
        $ret['product'] = $data;
        $this->load->view('products/edit', $ret);
    }
    else
    {
        $product = product_model::find($this->input->post('id'));
        $product->update_attributes($data);
        
        redirect('/products', 'refresh');
    }      
}


So, this all seems to work fine, but I have no idea if this follows 'good' practise or the conventions.

Thanks for any advice that you can give.
#2

[eluser]SitesByJoe[/eluser]
You're right. That works.

Things you can do to clean up a little more:

1. Make and use the form_validation config file (config/form_validation.php) and use it like described in the user guide.

2. You can just have one function do both operations (edit and update) using this structure:

Code:
function edit()
{
    if ($this->form_validation->run('see #1') == FALSE)
    {
         // show the form or error messages
    }
    else
    {
         // process our form stuff into an array
         $record = array('fieldname' => $this->input->post('fieldname'));

         // save the record changes
         $this->db->where('id', $this->input->post('id');
         $this->db->update('table', $record);

         // make a success message to potentially show our user
         $this->session->set_flashdata('message', 'success!');

         // move along to new screen
         redirect('success-page');
    }
}
#3

[eluser]InsiteFX[/eluser]
I would add the second parameter to tell it to XSS clean the input data.

Code:
$this->input->post('id', TRUE);

InsiteFX
#4

[eluser]JonoB[/eluser]
Thank you for the replies. That (mostly) makes sense.

The part that I dont get it how I combine the edit and update into one controller. At the moment, the controller index shows a table of all products, clicking on one of those invokes the edit function, with the ID of the product being passed in as a parameter.

Does your suggestion mean that I should post back to the same form, validate the input, and then either reshow the same form (validation failed), or go the product/index (validation passed)?

Code:
function edit($id = '')
{
    if ($id)
    {
        $data['product'] = product_model::find($id)->to_array();
        $data['message'] = '';
  
        $data['title'] = 'Edit Product';
        $data['action'] = site_url('products/update');
        $data['link_back'] = anchor('products', 'Back to list of products', array('class' => 'back'));

        $this->load->view('products/edit', $data);      
    }
    else if ($_POST && $this->form_validation->run() == FALSE)
    {
         // show the form or error messages
    }
    else if ($_POST)
    {
         // process our form stuff into an array
         $record = array('fieldname' => $this->input->post('fieldname'));

         // save the record changes
         $this->db->where('id', $this->input->post('id');
         $this->db->update('table', $record);

         // make a success message to potentially show our user
         $this->session->set_flashdata('message', 'success!');

         // move along to new screen
         redirect('success-page');
    }
}




Theme © iAndrew 2016 - Forum software by © MyBB