Text field in Rails stores string instead of Hash - ruby

I am designing a controller that handles the receipts for my E-commerce site. This is what the JSON params look like:
{
"receipt": {
"items": {
"item1": {
"price": "22.11",
"quantity": "2",
"name": "Name",
"discount": 0.04
},
"item2": {
"price": 12.11,
"quantity": 1,
"name": "Name"
},
"item3": {
"price": 21.11,
"quantity": 1,
"name": "Name",
"discount": 0.14
}
},
"payment_type": "Credit Card",
"payment_provider": "Visa",
"paid_status": true,
"total": 22
}
}
The items field is a text field in the database and I am using serialize to convert it to hash:
serialize :receiptitems, Hash
My strong params are defined in this way:
params.require(:receipt).permit(:payment_type, :payment_provider, :paid_status, :total, items: params[:receipt][:items].try(:keys))
Since the items are dynamically generated I now receive an error:
Unpermitted parameters: item1, item2, item3
How can I fix this? I tried tap method and it did not work as well.

You need to add the line
accepts_nested_attributes_for :price, :quality, :name, :discount
http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

Related

How to apply filters to extra fields from model serializer that are not in the model with django Rest

We have the SecurityEventItem that have the owner taken from another security_location model and returned.
The logic behind not having security_location direct as a foreign key is that we get events with security_location names that are not added yet to database, but we want them to be registered without adding the missing security location to the database.
class SecurityEventItemGetSerializer(serializers.ModelSerializer):
epc = RfidTagNestedSerializer()
owner = serializers.SerializerMethodField('get_owner')
def get_owner(self, member):
location = SecurityLocationSerializer(models.SecurityLocation.objects.get(name=member.security_location)).data
owner_name = ProductOwnerSerializer(models.ProductOwner.objects.get(id=location["owner"])).data
return owner_name["owner_name"]
class Meta:
model = models.SecurityEventItem
fields = ["id", "epc", "acknowledged", "firstSeenTimestamp", "security_location", "owner"]
The ViewSet bellow
class SecurityEventItemGetViewset(viewsets.ModelViewSet):
"""SecurityEventItemGet Viewset
API endpoint that allows security event items to be viewed.
Allowed actions:
"GET"
"""
queryset = models.SecurityEventItem.objects.all()
serializer_class = serializers.SecurityEventItemGetSerializer
http_method_names = ['get']
filter_backends = [DjangoFilterBackend]
search_fields = ["owner"]
filterset_fields = {
'acknowledged': ['exact'],
'epc': ['exact', "in"],
'security_location': ['exact', "in"],
'firstSeenTimestamp': ['gte', 'lte'],
}
I have tryed SearchFilter unsuccesfull as simillar to DjangoFilterBackend it does not recognize the owner field added that does not belong to the SecurityEventItem model.
The response is like this: and I would like to make a filter on the request passing a parameter "owner" added to the existing ones.
[
{
"id": 73,
"epc": {
"id": 8371,
"number": "1234",
"product": {
"id": 1,
"name": "default_product",
"ean": "",
"description": "default product for foreign/unknown RFID tags",
"category": {
"id": 1,
"name": "default_category",
"description": "default category for foreign/unknown RFID tags"
},
"info": []
},
"state": 1,
"info": [],
"owner": {
"id": 1,
"owner_id": 1,
"owner_name": "George"
}
},
"acknowledged": false,
"firstSeenTimestamp": "2022-02-21T09:44:08",
"security_location": "Test Location",
"owner": "Second Owner"
},
{
"id": 72,
"epc": {
"id": 105177,
"number": "303625D4580B2484000002CA",
"product": {
"id": 590,
"name": "A78R07",
"ean": "5940000792305",
"description": "Fata de perna 50x70",
"category": {
"id": 1,
"name": "default_category",
"description": "default category for foreign/unknown RFID tags"
},
"info": "{\"company\": \"HOTEL Nr1\"}"
},
"state": 1,
"info": [],
"owner": {
"id": 1,
"owner_id": 1,
"owner_name": "Regina"
}
},
"acknowledged": false,
"firstSeenTimestamp": "2022-02-21T09:31:16",
"security_location": "Front Desk",
"owner": "Second Company"
}
]
I would really appreciate if someone could teach me how to do that, there are plenty of information regarding model filtering, but no filters for the filters added to extra fields
SerializerMethodField is read-only.
This field is generated only at the time of serialization and does not exist in the database.
Filters work only with the database, but the owner field is not there.
I think you should annotate the queryset with the data you want (.annotate(owner=...), Subquery() ), then the filter can work because that field will be returned from the database.

Orbeon: Static dropdown in repeated grid

I have a problem in repeated grid, I have a drop-down list where the users will choose what model they want.
Then I also have a JSON array which contains the model and other description of different cars.
How can I auto fill the appropriate JSON value to textField according to the chosen value in the drop-down list?
Like for example: The user chose the model Toyota, only the Toyota car model present in the JSON will be displayed at textField.
The form I've created is available at https://demo.orbeon.com/demo/fr/orbeon/builder/edit/3b1ebd5340007f245b34ccd468c36c188b376bd6. And here is the JSON:
{
"corppassUser": {
"corppassData": null,
"corppassEntity": {
"primaryActiviyDesc": "Marine insurance ",
"companyType": "A1",
"corppassPreviousNames": [],
"entityType": "LC",
"primaryActivityCode": "65121",
"businessExpiryDate": "",
"secondaryActivityCode": "93202",
"corppassShareholders": [
{
"allocation": 20000,
"personRef": {
"personName": "ANDY",
"nationality": "SG",
"id": 8,
"idno": "S6001111A"
},
"currency": "SGD",
"id": 3,
"entityRef": null,
"category": "1",
"shareType": "1"
},
{
"allocation": 10000,
"personRef": {
"personName": "TIMOTHY TAN",
"nationality": "SP",
"id": 6,
"idno": "S1112374E "
},
"currency": "SGD",
"id": 1,
"entityRef": null,
"category": "1",
"shareType": "1"
},
{
"allocation": 10000,
"personRef": {
"personName": "CLARISSA LIN",
"nationality": "SG",
"id": 7,
"idno": "S3212386E"
},
"currency": "SGD",
"id": 2,
"entityRef": null,
"category": "1",
"shareType": "1"
}
],
"uen": "T15LP0005A"
},
"id": 1
}
}

how can I iterate through this array of hashes to receive a particular value : RUBY

the hash I have is the following:
aoh=[
{ "name": "Vesper",
"glass": "martini",
"category": "Before Dinner Cocktail",
"ingredients": [
{ "unit": "cl",
"amount": 6,
"ingredient": "Gin" },
{ "unit": "cl",
"amount": 1.5,
"ingredient": "Vodka" },
{ "unit": "cl",
"amount": 0.75,
"ingredient": "Lillet Blonde" }
],
"garnish": "Lemon twist",
"preparation": "Shake and strain into a chilled cocktail glass." },
{ "name": "Bacardi",
"glass": "martini",
"category": "Before Dinner Cocktail",
"ingredients": [
{ "unit": "cl",
"amount": 4.5,
"ingredient": "White rum",
"label": "Bacardi White Rum" },
{ "unit": "cl",
"amount": 2,
"ingredient": "Lime juice" },
{ "unit": "cl",
"amount": 1,
"ingredient": "Syrup",
"label": "Grenadine" }
],
"preparation": "Shake with ice cubes. Strain into chilled cocktail glass." }]
How can I iterate through this to get JUST the ingredient (without returning name,glass,category,etc.)? I also need the same iteration for amount but I assume that will look just like the iteration for ingredient. Sorry for the dumb question, I'm new to ruby and have attempted this for hours now.
You have an array of two elements in your example. Those two elements are hashes with key/value pairs. You can loop through the array with the #each method and access the values that the :"ingredients" keys store like this:
aoh.each do |hash|
hash[:ingredients]
end
The :ingredients keys each store another array of hashes. An example hash is:
{ "unit": "cl",
"amount": 6,
"ingredient": "Gin" }
You can then access the value under the :ingredient key by doing hash[:ingredient]. The final result looks something like this:
aoh.each do |array_element|
array_element[:ingredients].each do |ingredient|
ingredient[:ingredient]
end
end
This currently only iterates through the arrays and hashes. If you want to also print the result you can do this:
aoh.each do |array_element|
array_element[:ingredients].each do |ingredient|
puts ingredient[:ingredient]
end
end
#=> Gin
# Vodka
# Lillet Blonde
# White rum
# Lime juice
# Syrup
If you want to get a modified array, you can use #map (or #flat_map). You can also get the amount with the value like this:
aoh.flat_map do |array_element|
array_element[:ingredients].map do |ingredient|
[[ingredient[:ingredient], ingredient[:amount]]
end
end
#=> [["Gin", 6], ["Vodka", 1.5], ["Lillet Blonde", 0.75], ["White rum", 4.5], ["Lime juice", 2], ["Syrup", 1]]
>aoh.collect { |i| i[:ingredients].collect { |g| puts g[:ingredient] } }
Gin
Vodka
Lillet Blonde
White rum
Lime juice
Syrup
I would suggest the following.
aoh=[
{ "name": "Vesper",
"ingredients": [
{ "unit": "cl", "ingredient": "Gin" },
{ "unit": "cl", "ingredient": "Vodka" }
],
"garnish": "Lemon twist"
},
{ "name": "Bacardi",
"ingredients": [
{ "unit": "cl", "ingredient": "White rum" },
{ "unit": "cl", "ingredient": "Lime juice" }
],
}
]
aoh.each_with_object({}) { |g,h| h[g[:name]] =
g[:ingredients].map { |f| f[:ingredient] } }
#=> {"Vesper"=>["Gin", "Vodka"], "Bacardi"=>["White rum", "Lime juice"]}

Need Mongodb schema validator script for the given schema

Hi all i have been trying out various combination in the last few days to pinpoint how to create schema validator. Meaning a collection wont just take any input but will accept only what is given in the validator.
I created below collection via mongo-repository in spring.
Can you please provide the validator for the same. And also give links which will do complex mongodb collections to java pojo mapping. It would be of great help. All i found was simple validators or java to mongo collection not vice versa
{
"_id": {
"$numberInt": "1"
},
"listOfItems": [
{
"itemid": {
"$numberInt": "1"
},
"qty": {
"$numberInt": "10"
},
"qty_type": "kg",
"cost": "20",
"currency": "INR"
},
{
"itemid": {
"$numberInt": "2"
},
"qty": {
"$numberInt": "10"
},
"qty_type": "kg",
"cost": "20",
"currency": "INR"
},
{
"itemid": {
"$numberInt": "3"
},
"qty": {
"$numberInt": "10"
},
"qty_type": "kg",
"cost": "20",
"currency": "INR"
}
],
"_class": "com.daily.essential.cartservice.model.Cart"
}
//this should answer your question
const mongoose = require('mongoose');
const productSchema = mongoose.Schema({
//mongoose generates a new rando unique Id for the product
_id: mongoose.Schema.Types.ObjectId,
//mongoose makes sure that the name input by the user is a string and mongoose makes the /name field required that means the user must not leave the field empty.
name: {type: String, required: true},
//mongoose makes sure that the price input by the user is a a Number and mongoose makes //the price field required that means the user must not leave the field empty.
price: {type: Number, required: true}
});
module.exports = mongoose.model('Product', productSchema);

JSON object stored in a database table. (How to access)

I have a column name payment_data in my database table. data was stored as JSON array using json_encode().
I want to parse the JSON array in my datatable. But I fail.
this is the data that I want to access
payment_data column
I updated my data structure to this.
Array[2][
{
"po_id": 43,
"full_name": "Dawn Zulita",
"level": "organization",
"payment_data": {
"product_id": "184",
"product_name": "Grading Org Product",
"student_name": {
"0": "Eloise Phillips",
"1": "Lara vel"
}
},
"date_purchase": "2018-08-10 10:38:08"
},
{
"po_id": 42,
"full_name": "QWerty You",
"level": "school",
"payment_data": {
"product_id": 185,
"product_name": "School Owner Manual Payment School Owner Manual Payment",
"student_name": {
"0": "Jai Who",
"1": "Charlie Putt",
"2": "Kevin Young"
}
},
"date_purchase": "2018-08-09 14:53:35"
}
]
I can now access the payment_data.product_name,
{
data: 'payment_data.product_id'
},
{
data: 'payment_data.product_name'
},
but the problem is I cannot access payment_data.student_name
error return Undefined index
{
data: 'payment_data.student_name'
},

Resources