Rails update remove number from an array attribute? - arrays

Is there a way to remove a number from an attibute array in an update? For example, if I want to update all of an alchy's booze stashes if he runs out of a particular type of booze:
Alchy has_many :stashes
Stash.available_booze_types = [] (filled with booze.ids)
Booze is also a class
#booze.id = 7
if #booze.is_all_gone
#alchy.stashes.update(available_booze_types: "remove #booze.id")
end
update: #booze.id may or may not be present in the available_booze_types array
... so if #booze.id was in any of the Alchy.stash instances (in the available_booze_types attribute array), it would be removed.

I think you can do what you want in the following way:
if #booze.is_all_gone
#alchy.stashes.each do |stash|
stash.available_booze_types.delete(#booze.id)
end
end
However, it looks to me like there are better ways to do what you are trying to do. Rails gives you something like that array by using relations. Also, the data in the array will be lost if you reset the app (if as I understand available_booze_types is an attribute which is not stored in a database). If your application is correctly set up (an stash has many boozes), an scope like the following in Stash class seems to me like the correct approach:
scope :available_boozes, -> { joins(:boozes).where("number > ?", 0) }
You can use it in the following way:
#alchy.stashes.available_boozes
which would only return the ones that are available.

Related

Use content of a tuple as variable session

I extracted from a previous response an Object of tuple with the following regex :
.check(regex(""""idSc":(.{1,8}),"pasTemps":."codePasTemps":(.),"""").ofType[(String,String)].findAll.saveAs ("OBJECTS1"))
So I get my object :
OBJECTS1 -> List((1657751,2), (1658105,2), (4557378,2), (1657750,1), (916,1), (917,2), (1658068,1), (1658069,2), (4557379,2), (1658082,1), (4557367,1), (4557368,1), (1660865,2), (1660866,2), (1658122,1), (921,1), (922,2), (923,2), (1660875,1), (1660876,2), (1660877,2), (1658300,1), (1658301,1), (1658302,1), (1658309,1), (1658310,1), (2996562,1), (4638455,1))
After that I did a Foreach and need to extract every couple to add them in next requests So we tried :
.foreach("${OBJECTS1}", "couple") {
exec(http("request_foreach47"
.get("/ctr/web/api/seriegraph/bydates/${couple(0)}/${couple(1)}/1552863600000/1554191743799")
.headers(headers_27))
}
But I get the message : named 'couple' does not support index access
I also though that to use 2 regex on the couple to extract both part could work but I haven't found any way to use a regex on a session variable. (Even if its not needed for this case but possible im really interessed to learn how as it could be usefull)
If would be really thankfull if you could provided me help. (Im using Gatling 2 but can,'t use a more recent version as its for work and others scripts have been develloped with Gatling2)
each "couple" is a scala tuple which can't be indexed into like a collection. Fortunately the gatling EL has a function that handles tuples.
so instead of
.get("/ctr/web/api/seriegraph/bydates/${couple(0)}/${couple(1)}/1552863600000/1554191743799")
you can use
.get("/ctr/web/api/seriegraph/bydates/${couple._1}/${couple._2}/1552863600000/1554191743799")

Logical-Indexing for Matlab-object-arrays

Is there any way in Matlab R2011b to apply logical-indexing to object-arrays? The objects which fulfill specific condition(s) regarding their properties should be returned. At best the solution is also possible with object-arrays that are a property of another object (aggregation).
In my project there are a lot of entities which have to be identified by their manifold features. Matlab objects with their properties provide a clear data foundation for this purpose. The alternative of using structs (or cells) and arrays of indices seems to be too confusing. Unfortunately the access to the properties of objects is a little bit complicated.
For Example, all Objects in myArray with Element.val==3 should be returned:
elementsValIsThree = myElements(Element.val==3);
Best solution so far:
find([myElements.val]==3);
But this doesn't return the objects and not the absolute index if a subset of myElements is input.
Another attempt returns only the first Element and needs constant properties:
myElements(Element.val==3);
A minimal example with class definition etc. for clarification:
% element.m
classdef Element
properties
val
end
methods
function obj = Element(value)
if nargin > 0 % to allow empty construction
obj.val = value;
end
end
end
end
Create array of Element-Objects:
myElements(4) = Element(3)
Now myElements(4) has val=3.
I'm not sure I understood the question, but the logical index can be generated as
arrayfun(#(e) isequal(e.val,3), myElements);
So, to pick the elements of myElements whose val field equals 3:
elementsValIsThree = myElements(arrayfun(#(e) isequal(e.val,3), myElements));

Mongoid 4 update array attribute in a document

What is the mistake in this code for not be able to update an array within a document?
Model
class Foo
include Mongoid::Document
include Mongoid::Timestamps::Created
field :myarray, type: Array
end
Controller
def add_item
#foo = Foo.find_by(uuid: params[:uuid])
unless #foo.nil?
unless #foo.has_attribute? :myarray
#foo[:myarray] = Array.new
end
#foo[:myarray] << params[:item]
#foo.save
end
end
I am using Rails 4 with MongoId 4 and if I do p #foo before #foo.save I can see #foo correctly changed but for any reason the update is not persisted.
When you say this:
#foo[:myarray] << params[:item]
You're modifying the myarray array in-place so Mongoid probably won't recognize that it has changed. Then when you say #foo.save, Mongoid will look at #foo to see what has changed; but the array reference in #foo[:myarray] won't change so Mongoid will decide that nothing has changed and #foo.save won't do anything.
If you force a new array reference to be created by saying:
#foo[:myarray] += [ params[:item] ] # Or anything else that creates a whole new array
then Mongoid will notice that #foo[:myarray] has changed and #foo.save will send the change down to MongoDB via $set operation on the underlying document.
This looks like the Mongoid version of this ActiveRecord problem with PostgreSQL array columns:
New data not persisting to Rails array column on Postgres
The rule of thumb is "don't edit mutable values in-place, create whole new values instead: copy, edit, replace". That way you don't have to worry about manually managing the "is dirty" flags.

pattern for updating a datastore object

I'm wondering what the right pattern should be to update an existing datastore object using endpoints-proto-datastore.
For example, given a model like the one from your GDL videos:
class Task(EndpointsModel):
detail = ndb.StringProperty(required=True)
owner = ndb.StringProperty()
imagine we'd like to update the 'detail' of a Task.
I considered something like:
#Task.method(name='task.update',
path='task/{id}',
request_fields=('id', 'detail'))
def updateTask(self, task):
pass
However, 'task' would presumably contain the previously-stored version of the object, and I'm not clear on how to access the 'new' detail variable with which to update the object and re-store it.
Put another way, I'd like to write something like this:
def updateTask(self, task_in_datastore, task_from_request):
task_in_datastore.detail = task_from_request.detail
task_in_datastore.put()
Is there a pattern for in-place updates of objects with endpoints-proto-datastore?
Thanks!
See the documentation for details on this
The property id is one of five helper properties provided by default
to help you perform common operations like this (retrieving by ID). In
addition there is an entityKey property which provides a base64
encoded version of a datastore key and can be used in a similar
fashion as id...
This means that if you use the default id property your current object will be retrieved and then any updates from the request will replace those on the current object. Hence doing the most trivial:
#Task.method(name='task.update',
path='task/{id}',
request_fields=('id', 'detail'))
def updateTask(self, task):
task.put()
return task
will perform exactly what you intended.
Task is your model, you can easily update like this:
#Task.method(name='task.update',
path='task/{id}',
request_fields=('id', 'detail'))
def updateTask(self, task):
# Task.get_by_id(task.id)
Task.detail = task.detail
Task.put()
return task

GoogleAppEngine - query with some custom filter

I am quite new with appEnginy and objectify. However I need to fetch a single row from db to get some value from it. I tried to fetch element by ofy().load().type(Branch.class).filter("parent_branch_id", 0).first() but the result is FirstRef(null). However though when I run following loop:
for(Branch b : ofy().load().type(Branch.class).list()) {
System.out.println(b.id +". "+b.tree_label+" - parent is " +b.parent_branch_id);
};
What do I do wrong?
[edit]
Ofcourse Branch is a database entity, if it matters parent_branch_id is of type long.
If you want a Branch as the result of your request, I think you miss a .now():
Branch branch = ofy().load().type(Branch.class).filter("parent_branch_id", 0).first().now();
It sounds like you don't have an #Index annotation on your parent_branch_id property. When you do ofy().load().type(Branch.class).list(), Objectify is effectively doing a batch get by kind (like doing Query("Branch") with the low-level API) so it doesn't need the property indexes. As soon as you add a filter(), it uses a query.
Assuming you are using Objectify 4, properties are not indexed by default. You can index all the properties in your entity by adding an #Index annotation to the class. The annotation reference provides useful info.
Example from the Objectify API reference:
LoadResult<Thing> th = ofy.load().type(Thing.class).filter("foo", foo).first();
Thing th = ofy.load().type(Thing.class).filter("foo", foo).first().now();
So you need to make sure member "foo" has an #Index and use the now() to fetch the first element. This will return a null if no element is found.
May be "parent_branch_id"in your case is a long, in which case the value must be 0L and not 0.

Resources