My code in ServiceDetailController
$users = $this->ServiceDetail->Users->find()->extract('first_name')->where(['position' => 2]);
I get an error:
Call to undefined method Cake\ORM\ResultSet::where()
Debugging basics: Check if the method exists in the called object. If not ask yourself why. Then check what extract() returns and you'll get your answer. You basic problem, as a metaphor is that you try to drink from a bottle before opening it. You can't extract without having a result first.
Extract does not return a query object. First build your query, then execute it, all() for example, and then call extract on the result object because it implements a collection that allows you to call extract() on it.
Related
I have some ruby code from my Ruby on Rails project.
I am formatting some data so I am calling attributes.extract! to get the fields I need from my model.
I noticed recently that every now and then the data wouldn't get extracted as expected. I realized that I needed a splat operator. But it is strange because I do notice that sometimes when the method is called in my Rails project it will sometimes extract the data without the use of the splat operator. But when I run the code from my Rails console it never extracts the data unless I add the splat operator.
Here is the code in question
# in a service file, let's call it service.rb
def self.format_user_home_address_data(user)
# This doesn't work in the console but sometimes works when run in my Rails project
home_address_data = user.attributes.extract!(User::HOME_ADDRESS_FIELDS)
home_address_data[:address_type] = "home"
home_address_data
end
# at the end this method will sometimes return { address_type: "home" } or
# sometimes it'll actually return the extracted attributes as expected
HOME_ADDRESS_FIELDS is just an array with the values ["address_line_1", "city", "state", "zip"]
Anyway I know that to get it to run correctly I need to do this
home_address_data = user.attributes.extract!(*User::HOME_ADDRESS_FIELDS)
But does anyone know why I was able to get away without adding the splat operator for so long? Is there some Ruby on Rails magic that is only sometimes happening? What's the deal?
Well, let's check it out. There is no any magic behind attributes.extract! in the end. Here is an actual implementation of this method from Rails source code:
def extract!(*keys)
keys.each_with_object(self.class.new) { |key, result|
result[key] = delete(key) if has_key?(key)
}
end
Link: click. As you can see, it creates new hash, goes over the keys one by one and moves value from self to this new array. So, if you give an Array argument to this method then key in the block will be an Array as well. So, it won't be found. So, no way it may work for array argument. The only one possibility is that something else is passed instead of User::HOME_ADDRESS_FIELDS.
I keep coming across this issue where I am trying to update a record using the update() method.
It always works when I query an object using filter.
my_dictionary = {"key":"Val","another":"Val"}
thing = Thing.objects.filter(pk=1)
thing[0].update(**my_dictionary) wrote it wrong in the original question.
thing.update(**my_dictionary)
When I query the object using get() it keeps telling me that the object has no method update()
my_dictionary = {"key":"Val","another":"Val"}
thing = Thing.objects.get(pk=1)
thing.update(**my_dictionary)
Isn't a model object the same in both cases? Why would one have an update method and the other one not? Any insight would be greatly appreciated.
The documentation is very explicit about this:
filter() will always give you a QuerySet, even if only a single object matches the query - in this case, it will be a QuerySet containing a single element.
If you know there is only one object that matches your query, you can use the get() method on a Manager which returns the object directly.
Your first snippet returns a QuerySet, which has an update method. The second snippet returns a model instance, which doesn't.
Note that you have not shown the exact code you are using: thing[0].update would give exactly the same error as the second snippet.
You're using QuerySet.update() and ModelInstance.save().
If you’re just updating a record and don’t need to do anything with the model object, the most efficient approach is to call update(), rather than loading the model object into memory. For example, instead of doing this:
e = Entry.objects.get(id=10)
e.comments_on = False
e.save()
...do this:
Entry.objects.filter(id=10).update(comments_on=False)
Im a newbie to Django and would like to understand what is the difference between filter vs get
Get
Entry.objects.get(id__exact=14)
Filter
Entry.objects.filter(id__exact=14)
What difference the above statement makes?
Thanks in advance.
the get only brings an element that is equal to what you're looking for but the filter brings everything related to that item you want.
filter returns many things found.
get returns only one thing to what you're looking for
for example:
GET
Task.objects.get(id=1,status=1)
Filter
Groups.objects.filter(user=1)
Basically use get when you want to get a single unique object, and filter when you want to get all objects that match your lookup parameters
__data = User.objects.get(is_active=1).exclude(id=id)
Error:get() returned more than one User -- it returned 19!,
Type:<class 'django.contrib.auth.models.MultipleObjectsReturned'>
------successful-------
__data = User.objects.filter(is_active=1).exclude(id=id)
-------successful------
Check the Link
To add to what others have said... (get returns exactly 1 record, while filter returns a set), an important thing to note is the type of the results.
get() returns an object, while filter returns a queryset type. This means you can do something like
age = User.objects.get(name="Ryan").age
Whereas if you were using filter, you'd need to do a couple extra steps:
ages = User.Objects.filter(name="ryan").values('age')
for user_age in users:
print(user_age)
The important thing to note is that filter returns an iterable type with a values() method dictating which fields you want. Get simply returns an object with the fields as attributes, so it is much simpler to get the data you need.
If you know it's one object that matches your query, use get. It will fail if it's more than one, and gives the error like this:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 143, in get
return self.get_query_set().get(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 407, in get
(self.model._meta.object_name, num))
MultipleObjectsReturned: get() returned more than one Poll -- it returned 2!
Otherwise use filter, which gives you a list of objects.
I am fetching data in array and its get data when I use print_r function but when I display the array its said undefined data field.
any way to display result array();? I don't want to use a foreach loop.
The code is:
$menu2=$this->load->common_model->getRecord('*','inner_menu','menu_page',2);
if ( $menu2->num_rows() > 0) {
$page1 = $menu2->result_array();
print_r($page1);
<?=$page1['url']?>// here it said undeifned variable url
// url is in my db tabel inner_menu
}
Your syntax is really off, or you're using CodeIgniter in a really strange or unacceptable way.
First, you should be loading your models like this:
$this->load->model('common_model');
$this->common_model->getRecord();
Your getRecord() method should be one that throws result_array() to the controller and not the controller calling upon it.
Second, in order to get a better understanding, we would need to see some sample code of getRecord() for us to help you.
I did a separate levelData class to be able to flexibly add levels. I was happy with it until my supervisor ordered me to convert my levelData into XML. I did an XML version of the levelData's data (question, answers, correct answer...). I used the old class and converted it so that it fetches the XML.
All seems well, I did traces of my answers array and it printed nicely...
But the headache started when I tried this.
// This code appears in a different class with
// currentLvl:LevelData initialized in the constructor.
quizHolder.ansA.ansHud.text = currentLvl.choices[1];
quizHolder.ansB.ansHud.text = currentLvl.choices[2];
quizHolder.ansC.ansHud.text = currentLvl.choices[3];
quizHolder.ansD.ansHud.text = currentLvl.choices[4];
// BTW, I can't make a for loop to do the same function as above. So wierd.
I tried to run it. it returned:
TypeError: Error #2007: Parameter text must be non-null.
at flash.text::TextField/set text()
at QuestionPane/setQuiz()
at QuestionPane/setQuestion()
at QuestionPane()
at LearningModule()
Where did I go wrong? I tried making a custom get function for it, only to get the same error. Thanks in advance. If I need to post more of the code, I will gladly do so =)
LevelData Class in PasteBin: http://pastebin.com/aTKC1sBC
Without seeing more of the code it's hard to diagnose, but did you correctly initialize the choices Array before using it? Failing that I think you'll need to post more code.
Another possible issue is the delay in loading the XML data. Make sure your data is set before QuestionPane tries to access it.
When did you call
quizHolder.ansA.ansHud.text = currentLvl.choices[1];
quizHolder.ansB.ansHud.text = currentLvl.choices[2];
quizHolder.ansC.ansHud.text = currentLvl.choices[3];
quizHolder.ansD.ansHud.text = currentLvl.choices[4];
these? You load the XML and on complete you fill the array, what is correct. but is the XML loaded and parsed to the time when you access (fill the TextFields) the choices array already?