Ruby Rails - save vs update where method - ruby

I am trying to make a inventory system, my table has the index "id" by default as primary key. My inventory number should be unique value to create new entry in the table, if the inventory already exists then it shall update the attributes. How do do this? By making inventory number as primary key? or is there any way to check and update an inventory already exists?

You can have unique field number (for example). Than you can use find_or_create_by_<field_name> dirty method.
#ticket = Ticket.find_or_create_by_number(503)
Updated:
#ticket.attrib = 'new attribute value'
#ticket.save
or
#ticket.update_attribute :attrib, 'new attribute value'

This worked: create_or_update method in rails
my_class = ClassName.find_or_initialize_by_name(name)
my_class.update_attributes({:street_address => self.street_address,.....})

Related

Odoo 10 - Duplicate supplier info for a given product_template

I have:
a) given product_template_id (i.e. id 100) and
b) a duplicated product_template_id (i.e. id 200) created using copy() method
copy() method copies only product.template model, so suppliers for that specific product are not copied.
I would like to duplicate all suppliers for that model, but now I am wondering which is the right way to do it in Odoo.
If I understood the model properly suppliers prices for a given product are stored in product_supplierinfo table, where each record that points to a given product_tmpl_id specifices a supplier price/qty for a given product_template.
Which would be the way in Odoo to search for all records that point to a given product_tmpl_id (i.e. 100), duplicate them changing product_tmpl_id to the new one (i.e. 200)?
Excerpt from the ORM Documentation:
copy (bool) -- whether the field value should be copied when the record is duplicated (default: True for normal fields, False for One2many and computed fields, including property fields and related fields)
The field you're referring to is seller_ids, whose field definition is below:
seller_ids = fields.One2many('product.supplierinfo', 'product_tmpl_id', 'Vendors')
The copy attribute is not explicitly defined, so it is False by default (as explained in the documentation above). If you want this field to copy along with the other values during the standard product "Duplicate" (copy method), you can do this:
class ProductTemplate(models.Model):
_inherit = 'product.template'
# This only changes the copy attribute of the existing seller_ids field.
# All other attributes (string, comodel_name, etc.) remain as they are defined in core.
seller_ids = fields.One2many(copy=True)
Alternatively
If you want to only have the field copied sometimes, you can extend the copy method to look for a specific context value and only copy based on that.
# This may take some tweaking, but here's the general idea
#api.multi
def copy(self, vals):
new_product = super(YourClass, self).copy(vals)
if vals.get('copy_sellers'):
new_product.seller_ids = self.seller_ids.copy({'product_id': new_product.id})
return new_product
# Whatever you have calling the copy method will need to include copy_sellers in vals
vals.update({'copy_sellers': True})
product.copy(vals)

ruby sequel gem - how to query arrays with the pg_array extension

I am using the pg_array extension and sequel version 4.1.1.
I have added the extension like this:
Sequel::Database.extension :pg_array
I have created a column like this:
alter_table :emails do
add_column :references, "text[]", null: true
end
I can load and retrieve arrays into a postgress array column, just like working with normal arrays.
What is not clear from the above link is how do I execute a query based on the values in this array column.
For example, if one row in the emails table contained these values in the references column:
references
--------------------------------------------------------------------
{}
{5363f773bccf9_32123fe75c45e6f090953#Pauls-MacBook-Pro.local.mail}
How can I query the emails table to find a row that contains a references array value of the above value:
Email.where(references: ????)
Use the pg_array_ops extension:
Sequel.extension :pg_array_ops
Email.where(Sequel.pg_array_op(:references).contains('5363f773bccf9_32123fe75c45e6f090953#Pauls-MacBook-Pro.local.mail'))
Have you tried?
ref = '5363f773bccf9'
emails = Email.arel_table
Email.where( emails[ :references ].matches( "%#{ref}%" ))

How to check included ID or not?

I have ActiveRecord collection and a I want to check my ID in it.
#items_user_id = Item.select("DISTINCT user_id").where(:user_id => current_user.id)
and I check
#items_user_id.include?(params[:id])
returned nil
What's wrong?
UPD 1 : What I need - param[:id] contains id of Item. The user can edit the items created by them only. And I want to check whether the item identifier in the identifier pool items user.
In short: you are comparing Apples to Oranges.
Long Answer:
#items_user_id = Item.select("DISTINCT user_id").where(:user_id => current_user.id) this line will return Array of Item elements.
params[:id] would possibly be String or Integer so it would not be found in the Array.
The select you do executes this query:
SELECT DISTINCT user_id FROM items WHERE user_id = ?
That will yield either nothing, or a single row with just the user_id.
What do you really want?
Try to collect the ids from the array obtained and then check..
#items_user_id.map(&:id).include?(params[:id])
Make sure the datatype of ids(string) matches with params[:id]

Sequel Migration update with a row's ID

How can you run a Sequel migration that updates a newly added column with a value from the row?
The Sequel documentation shows how you can update the column with a static value:
self[:artists].update(:location=>'Sacramento')
What I need to do is update the new column with the value of the ID column:
something like:
self[:artists].each |artist| do
artist.update(:location => artist[:id])
end
But the above doesn't work and I have been unable to figure out how to get it to go.
Thanks!
artist in your loop is a Hash, so you are calling Hash#update, which just updates the Hash instance, it doesn't modify the database. That's why your loop doesn't appear to do anything.
I could explain how to make the loop work (using all instead of each and updating a dataset restricted to the matching primary key value), but since you are just assigning the value of one column to the value of another column for all rows, you can just do:
self[:artists].update(:location=>:id)
if you need update all rows of a table, because it is a new column that need be populate
artists = DB[:artists]
artists.update(:column_name => 'new value')
or if you need, update only a unique row into your migration file you can:
artists = DB[:artists]
artists.where(:id => 1).update(:column_name1 => 'new value1', :column_name2 => "other")

Magento addFieldToFilter allow NULLs

When using the Magento collection method addFieldToFilter is it possible to allow filtering by NULL values? I want to select all the products in a collection that have a custom attribute even if no value is assigned to the attribute.
I see you already found a solution, but there is also this option:
$collection->addFieldToFilter('parent_item_id', array('null' => true));
But if you want to use "NULL" => false, which DOESN'T WORK.
(and I noticed you can use elements such as "in", "nin", "eq", "neq", "gt"), you can do this:
$collection->addFieldToFilter('parent_item_id', array('neq' => 'NULL' ));
Hope this is still helpful...
This works for NOT NULL filters
$collection->addFieldToFilter('parent_item_id', array('notnull' => true));
Filtering a product collection by null/empty attributes has two possible solutions. Magento uses an INNER JOIN to grab the values of the attributes to filter. BUT if the product attribute is not assigned a value the join will fail, as a database table / relationship is missing.
Solution #1: Use addAttributeToFilter() and change the join type from "inner" (the default) to "left":
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToFilter('custom_attribute', array( ... condition options ..), 'left');
Solution #2: Make sure your custom attribute has a default value. Magento is conservative in this regard. Magento will only create the relationship between an attribute and a product if a value is given for the attribute. So in the absence of user-specified value or a default value the attribute will not be accessible for filtering a product even if the attribute appears in the product detail view under the admin panel.
Because the question does not match exactly the title of the question and I found the them multiple times by searching for a condition like: special VALUE OR NULL
If you want to filter a collection matching a VALUE OR NULL, then you can use:
$collection->addFieldToFilter('<attribute>', array(
array('eq' => '<value>'),
array('null' => true)
));
You don't need to use addFieldToFilter.
now the solution:
attributes name is known as code in magento, you just need to use the code below to get all of the products which have a specific attribute as an array
$prodsArray=Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('custom_attribute_code')
->getItems();
you can also specify certain conditions for attribute's value in addAttributeToFilter in the second parameter of addAttributeToFilter.
you can find this method in this file (for further study):
app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php

Resources