Check existence of a relation in a model - yii

I have a parent model ParentModel, and in it I want to check if ChildModel has a relation, say, user or not.
I try something like:
$relation = "user";
if (isset($this->$relation)){
// dosomething
}
but the condition is always false even when the relation actually exists.
I know it is a naive question.... :( okay, sue me, I can't find the answer!

Try:
$relation = "user";
if (!empty($this->$relation)){
// dosomething
}

I find an answer
isset($this->relations()[$relation])

Related

Ruby on Rails find_by case insensitive

I need to find a record from 2 parameters but I need one of them to be case insensitive. The current case sensitive line is
c = Course.find_by(subject_area: area, cat_number: cat)
But I need subject_area to be case insensitive. How would I achieve that?
It depends on the database, and you may need to pass in db-specific SQL for that (and not use find_by).
Are you using postrges? if so, this would normally work:
Course.where("LOWER(subject_area) = ? AND cat_number = ?", area.downcase, cat)
alternatively you could convert your subject_area to downcase every time you save a new one... then just use:
Course.find_by(subject_area: area.downcase, cat_number: cat)
I could be wrong, but don't currently know of any rails-native way of doing a case insensitive rails find_by
An alternative can be
c = Course.find_by("LOWER(subject_area)= ? AND cat_number = ?", area.downcase, cat)
If you are using postgres, you could do something like:
> c = Course.find_by('subject_area ILIKE ? AND cat_number LIKE ?', area, cat)
(ILIKE is used to do insensitive search)
If you need to have this attribute be case-insensitive then the right way is to ensure it's always one particular in your model
before_save { self.subject_area = subject_area.downcase }
You can migrate your existing data to be downcased as well.
Having done that your find by operation still needs to ensure that the area is downcased in query as suggested.
Course.find_by(subject_area: area.downcase, cat_number: cat)
Option 2:
I knew I was forgetting this. Let's say you dont want to go migration path. Just define a scope.
http://guides.rubyonrails.org/v4.1/active_record_querying.html#scopes
scope :area_nocase, (area) -> { where("LOWER(subject_area) = ?", area.downcase) }
then you can use it like
Course.area_nocase(area) or cat.course.area_nocase(area)
or chain it however you need to.

django "use_natural_foreign_keys=True" issue

I currently use the well documented "use_natural_foreign_keys=True" to return the relevant field data required instead of the id:
all_orders = Orders.objects.all()
resp = serializers.serialize('json', all_orders, use_natural_foreign_keys=True)
What I don't know how to do is return both the id AND the field data required as typically returned by the "use of use_natural_foreign_keys=True".
Anyone know of a quick fix to return both?
Many thanks, Alan.
define a "natural_key" method in your model class, whose id and field_name you like to get. e.g
def natural_key(self):
return (self.id, self.field_name)

Storeing user's last login timestamp

Important Edit: There was not a programming error
That was a mistake by me and resulted to the problem. Please read the problem below:
I want to update user's last login's timestamp after I see that the user has logged in with below login() function at user_model.php.
public function login($username, $password)
{
$this->db->select('id, username, email, type, language, lastlogintimestamp');
$this->db->from('user');
$this->db->where('username', $username);
$this->db->where('password', $password);
$this->db->limit(1);
$result = $this->db->get();
if ($result->num_rows() > 0)
{
$this_user = $result->first_row();
$this->db->query(
'UPDATE `user` SET `lastlogintimestamp` = ? WHERE `id` = ? LIMIT 1',
array(time(), $this_user->id)
);
return $this_user;
}
return FALSE;
}
After the user has logged in successfully, $result->first_row() is stored into $this_user variable and after that I update the lastlogintimestamp.
So it's obvious that the old value of lastlogintimestamp should be returned.
THE PROBLEM is that very strangely I see that the new value is returned!!!
Very simple: Where I was seeing the result, was because of a very separate query like SELECT * FROM user.
There, I was seeing a list of users with their own lastlogintimestamps.
It's clear that I was seeing the updated lastlogintimestamps.
Anyway I should thank Prix for helping me find the problem via the comments. I think that the best I can do now with this question, is voting for it be close.
Considering the comments of my question, I got what I was doing wrong.
I should again thank #Prix for putting me in the right direction as he said in the last comment. (Read THIS comment and the next 3 ones)
I voted to close the question and accept it as an answer to be unanswered not.

Check if an existing value is in a database

I was wondering how I would go about checking to see if a table contains a value in a certain column.
I need to check if the column 'e-mail' contains an e-mail someone is trying to register with, and if something exists, do nothing, however, if nothing exists, insert the data into the database.
All I need to do is check if the e-mail column contains the value the user is registering with.
I'm using the RedBeanPHP ORM, I can do this without using it but I need to use that for program guidelines.
I've tried finding them but if they don't exist it returns an error within the redbean PHP file. Here's the error:Fatal error: Call to a member function find() on a non-object in /home/aeterna/www/user/rb.php on line 2433
Here's the code that I'm using when trying this:
function searchDatabase($email) {
return R::findOne('users', 'email LIKE "' . $email . '"');
}
My approach on the function would be
function searchDatabase($email) {
$data = array('email' => $email);
$user = R::findOne('users', 'email LIKE :email, $data);
if (!empty($user)) {
// do stuff here
} // end if
} // end function
It's a bit more clean and in your function
Seems like you are not connected to a database.
Have you done R::setup() before R::find()?
RedBeanPHP raises this error if it can't find the R::$redbean instance, the facade static functions just route calls to the $redbean object (to hide all object oriented fuzzyness for people who dont like that sort of thing).
However you need to bootstrap the facade using R::setup(). Normally you can start using RB with just two lines:
require('rb.php'); //cant make this any simpler :(
R::setup(); //this could be done in rb.php but people would not like that ;)
//and then go...
R::find( ... );
I recommend to check whether the $redbean object is available or whether for some reason the code flow has skipped the R::setup() boostrap method.
Edited to account for your updated question:
According to the error message, the error is happening inside the function find() in rb.php on line 2433. I'm guessing that rb.php is the RedBean package.
Make sure you've included rb.php in your script and set up your database, according to the instructions in the RedBean Manual.
As a starting point, look at what it's trying to do on line 2433 in rb.php. It appears to be calling a method on an invalid object. Figure out where that object is being created and why it's invalid. Maybe the find function was supplied with bad parameters.
Feel free to update your question by pasting the entirety of the find() function in rb.php and please indicate which line is 2433. If the function is too lengthy, you can paste it on a site like pastebin.com and link to it from here.
Your error sounds like you haven't done R::setup() yet.
My approach to performing the check you want would be something like this:
$count = count(R::find('users', 'email LIKE :email', array(':email' => $email)));
if($count === 0)
{
$user = R::dispense('users');
$user->name = $name;
$user->email = $email;
$user->dob = $dob;
R::store($user);
}
I don't know if it is this basic or not, but with SQL (using PHP for variables), a query could look like
$lookup = 'customerID';
$result = mysql_fetch_array(mysql_query("SELECT columnName IN tableName WHERE id='".$lookup."' LIMIT 1"));
$exists = is_null($result['columnName'])?false:true;
If you're just trying to find a single value in a database, you should always limit your result to 1, that way, if it is found in the first record, your query will stop.
Hope this helps

How to find a record that wasn't saved yet in Rails?

Say I have a record called Post that has many comments.
Now I run the following code:
p = Post.new
p.comments.build(:title => 'great')
I would now like to locate that comment by its title.
If the record was saved, I could do something like
p.comments.find_by_title('great')
But since it isn't saved yet, that's going to return nil (because it actually runs an SQL query)
Is there a way to locate this record before it's saved?
Thanks!
comment = p.comments.build(:title => "great")
great_comment = p.comments.detect{|c| c.title == 'great'}
Just write:
new_comment = p.comments.build(:title => 'great')
and new_comment will be the newly added comment.
Or, you could do something like:
new_comments = p.comments.select{|x| x.new_record?}
which would give you an array with all the unsaved comments.