Welcome Guest, Not a member yet? Register   Sign In
Passing a single array to a model
#1

[eluser]TheFuzzy0ne[/eluser]
Hi everyone. I was just wondering what people's opinions were on passing a single array as an argument to a model to use as the WHERE condition.

For example:
Code:
$where = array(
        'email' => $email
    );
$res = $this->user_model->get($where);

# OR

$where = array(
        'username' => $username
    );
$res = $this->user_model->get($where);

# OR

$where = array(
        'id' => $user_id
    );
$res = $this->user_model->get($where);

# OR

$where = array(
        'username' => $username,
        'password' => $password
    );
$res = $this->user_model->get($where);

Is this considered bad practice, and should I instead have more functions in my model? I just feel that having a model method for each case may be too much, but then again, perhaps it adds extra clarity? Obviously, there are also other things that need to be taken into account, such as limits, and the sort order of the results, so perhaps I shouldn't do it this way? What do you think?
#2

[eluser]TheFuzzy0ne[/eluser]
I'm bumping this as I'd really appreciate an answer.
#3

[eluser]n0xie[/eluser]
I would do something like this:

Code:
function foo ($someargument, $delimiter=FALSE){
if($delimiter){
   $this->db->where($delimiter);
}
}

But it depends on how many different delimiter cases you really need. Else I would just make several functions to improve readability:

Code:
function fooById()
function fooByName()
function fooByBar()

I'm not sure that is considered 'best practice'...
#4

[eluser]jedd[/eluser]
[quote author="TheFuzzy0ne" date="1236555639"]
Is this considered bad practice, and should I instead have more functions in my model?
[/quote]

You mean more publicly visible functions ..?

I'm looking at something similar at the moment, and I really like the abstraction approach (as you've done above), but I also like the approach of making my code self-documenting, and I think this approach doesn't satisfy quite like a series of
get_by_id() , get_by_username() , etc. (As you were intimating.)

At the moment I'm implementing a bunch of them - and I may have maybe a dozen or so for this one particular model. Within each of them, well for some of them, I then call to one of several private functions that do the actual lookups, as there's certain groupings of complexity, if you will, for some of these lookups. Others are very simple WHERE additions to a table lookup. And a couple require some messy JOINs. So I'm not sure how comparable my situation is to yours.

But, as I say, I prefer the readability of separate and more concisely name functions.

(ponder pulp) I think if we had real OO in PHP, it'd be nice to be able to overload the same function name with different input types and get 'redirected' in that fashion, but at the moment the extra code you (might) require to handle the different contents of your arrays that you're receiving .. well, I see the same amount of code being required, just it gets spread around into different places. Ie. no great saving over the multiple method calls approach.
#5

[eluser]TheFuzzy0ne[/eluser]
[quote author="n0xie" date="1236709129"]But it depends on how many different delimiter cases you really need. Else I would just make several functions to improve readability:

Code:
function fooById()
function fooByName()
function fooByBar()

I'm not sure that is considered 'best practice'...[/quote]

That's precisely my point. I'm not sure whether or not I should be repeating code like that. Or perhaps I should have a single private function, that deals with everything, and use those functions as aliases, which set the appropriate array data, pass it to the private function, and pass back the return data.

Thanks for your comments. Smile
#6

[eluser]xwero[/eluser]
why not use the parameters like some of the CI functions do
Code:
function get($field, $val='')
{
   if(is_string($field) && strlen($val)>0)
   {
      $field = array($field=>$val);
   }

   if( ! is_array($field))
   {
      return array();
   }

   $this->db->where($field);
   $query = $this->db_>get('table');

   return $query->result();
}
#7

[eluser]TheFuzzy0ne[/eluser]
[quote author="jedd" date="1236709857"]You mean more publicly visible functions ..?[/quote]

Indeed. I just want to avoid repeated code as much as possible. For getting a rows by ID or by Email, or by username for example, the code in each function would be virtually identical, apart from the WHERE condition.

[quote author="jedd" date="1236709857"]I'm looking at something similar at the moment, and I really like the abstraction approach (as you've done above), but I also like the approach of making my code self-documenting, and I think this approach doesn't satisfy quite like a series of
get_by_id() , get_by_username() , etc. (As you were intimating.)[/quote]

I agree. So where do we draw the line? Can we combine the two, or should we stick to one or the other?

[quote author="jedd" date="1236709857"]At the moment I'm implementing a bunch of them - and I may have maybe a dozen or so for this one particular model. Within each of them, well for some of them, I then call to one of several private functions that do the actual lookups, as there's certain groupings of complexity, if you will, for some of these lookups. Others are very simple WHERE additions to a table lookup. And a couple require some messy JOINs. So I'm not sure how comparable my situation is to yours.[/quote]

That's exactly what I was thinking of doing, but is this acceptable, and are we going to run into problem later down the line if we need to edit on of said private functions?

[quote author="jedd" date="1236709857"](ponder pulp) I think if we had real OO in PHP, it'd be nice to be able to overload the same function name with different input types and get 'redirected' in that fashion, but at the moment the extra code you (might) require to handle the different contents of your arrays that you're receiving .. well, I see the same amount of code being required, just it gets spread around into different places. Ie. no great saving over the multiple method calls approach.[/quote]

Personally, I think that would complicate things as you may not know for sure if you're accessing the right "version" of a particular function.

Thanks for your input.
#8

[eluser]TheFuzzy0ne[/eluser]
[quote author="xwero" date="1236710237"]why not use the parameters like some of the CI functions do
Code:
function get($field, $val='')
{
   if(is_string($field) && strlen($val)>0)
   {
      $field = array($field=>$val);
   }

   if( ! is_array($field))
   {
      return array();
   }

   $this->db->where($field);
   $query = $this->db_>get('table');

   return $query->result();
}
[/quote]

That was one of my thoughts, but I don't know whether or not it's considered a good way to do things, and also, I'm not sure. What if we needed to add limits and order by clauses into the mix? Perhaps I should just do this with CRUD? I tried using CRUD in the past, and we got along like Bill Gates using Linux... Perhaps it's time for me to start again? The trouble I had with crud was how to deal with multiple tables. Maybe it would just be easier for me to write a separate function for each case, and once everything is working, look towards optimising the code?

Thanks for your comments.
#9

[eluser]xwero[/eluser]
Everything depends on what you need to extract from the database and how much variation there is in extracting the data. In your example i think it would be overkill to create a method for each variation as the result is always one row or a false/empty result.

If the result of the method are rows from a table where the variations only request other fields it would be too much to create a method for each variation. But if the variations require different fields and limiting factors (where, order by, limit) i would create an other method.
Code:
funtion get_rows($fields)
{
   return $this->db->select($fields)->get('table');
}

function get_rows_where($where)
{
   return $this->db->select('field1,field2')->where($where)->get('table');
}

function get_select_rows_where($fields,$where)
{
   return $this->db->select($fields)->where($where)->get('table');
}
#10

[eluser]TheFuzzy0ne[/eluser]
Perhaps it's just me, but it still seems kind of complicated, especially when you add limits and order bys. Then again, perhaps this is a sign that I need to rethink my model? Often, I find myself calling the db straight from the controller with the intention of exporting them to the appropriate model methods at a later date.




Theme © iAndrew 2016 - Forum software by © MyBB