I need to update a Boolean and also create new records at the same time.
I have a controller called Bank, and Bank has 3 attributes, namely account:string, amount:decimal and withdrawn:Boolean, a customer can invest an amount for a specific number of days, after those days are reached they can then withdraw the amount with interest. I need that when the customer clicks withdraw the withdrawn Boolean is updated to true, and the amount+interest for example amount+10% is created and saved, the amount+10% result will also have a Boolean/flag paid which the “bank teller” can change to paid:, true after the cash payment is done.
How can I achieve the above, should I create a new controller and model for the Withdrawal, and how would that code look like?
No need to create a new controller. Just create a withdraw method in your controller. Not sure exactly what you mean with the amount+interest but I guess you're talking about another column in your database. Just add something like amount_with_interest as an attribute in the database. Also, add another column for paid, as a boolean.
def withdraw
the_bank = Bank.find(params[:id]) #or something similar to get the account one way or another
the_bank.withdrawn = true
the_bank.amount_with_interest = the_bank.amount * 1.1
the_bank.save
end
The teller can then press some other button somewhere after the payment has been sent that simply changes the_bank.paid to true
Related
I'm having some trouble understanding the correct way to go about this.
a user can subscribe to categories (8 total)
properties belong to categories
tickets can be created. Tickets can have either one or multiple properties.
if a ticket is created, and a user is subscribed to a category AND the created ticket includes that property, the user will receive an email notification.
This is what I had initially. I thought it was working decently, but the issue is:
if a ticket is created with multiple properties that span across different categories, and a user is only subscribed to one of those categories, they will not get the email. They should get an email.
example:
User A is only subscribed to one category: category one.
a ticket is created with 3 properties.
property 1 comes from category 1, property 2 comes from category 2, property 3 comes from category 3.
since User A is only subscribed to category one, they will not receive a ticket, but they should: hence an issue with my code.
I know the below is bad because that will only put the final property.category.name into #ticket_category
#ticket.properties.each do |property|
#ticket_category = property.category.name
end
#people_for_email = #sub_emails.select {|user| user["categories"].include?(#ticket_category)}
#emails_for_email = #people_for_email.map {|emails| emails["name"]}
then we send the email
UserNotifier.ticket_created(#emails_for_email).deliver_now
I've tried setting #ticket_category to an array [] and using << within the block. Using .any? seems like it would work well here, but I haven't had much luck setting it up without returning argument errors. Any idea the best way to go about this?
You can use & to get the intersection of two arrays. Then present? will return true if there are any elements in the array. So something like:
#ticket_categories = []
#ticket.properties.each do |property|
#ticket_categories << property.category.name
end
#people_for_email = #sub_emails.select do |user|
intersection = user["categories"] & #ticket_categories
intersection.present?
end
#emails_for_email = #people_for_email.map {|emails| emails["name"]}
(I didn't test this, so there might be typos)
This question has two parts:
Consider an active record relation that has a Student - name:string, favorite_class:references and FavoriteClass name:string, abbrev:string.
First question: When creating a student record and adding a favorite class (name and abbrev) I want to check if that name/abbrev combo exists and if it does load that one for this association, else create a new one.
Second: When I try to update (Put) the student I want to be able to pass the abbrev of the favorite class and look up the record by that portion (assuming abbrevs are unique) and use that, else fail.
I am not seeing the rails way of doing this type of operation.
For the first question, the trick is to use find_or_create method:
#in the place where you create a new Student
#this method return first entity from db, if it doesn't found, will create one
fav_class = FavoriteClass.find_or_create(name: some_name, abbrev: some_abbrev)
Student.create(name: some_student_name, favorite_class: fav_class)
something similar you can do for your second question. Please, give me more details about it.
Update 1
If you want to update student's favourite class, you can do it in this way:
#I assume that you use latest vertion of rails of not, use .first instead of .take
new_class = FavoriteClass.where(abbrev: some_abbrev).take
student.update_attributes(favorite_class: new_class) if new_class
I am wondering if, in some hidden corner of the API I haven't yet run into, if there is a way to clone an existing record into a new one, so when saved it will have a new id assigned?
This is intended to be used on an event site I am writing, which will allow people to import from previous years, but copying it will allow updating the event description with new content.
You can use dup method for this.
Given object user1 of model User, you can do:
user2 = user1.dup
user2.save
Doing user2 = user1.dup clones user1 into user2, and user2 has no id, created_at and updated_at values assigned and it is treated as a new record.
It's a bit difficult for me to put my questions in words, but I'll try.
I have two entities. One is called Product the other Sale. Each product has field definining the number of available items of this product. Each sale has a field stating the number of sold items of one product. Product to Sale is a OneToMany-Relationship.
Now if I want to find out if a product has sold out, I need to create a function which substracts the total number of sold items from the initial availability number of the product. Something like function getAvailableQuantity().
My question is: Where do I place this method?
I am tempted to put it in the Product Repository - but since this method needs to access the Sales entity this is against Dependency Injection. However, placing it in the controller seems like an unnecessary detour as I am losing the possibility of calling {{ product.getAvailableQuantity }} in Twig templates.
What is the way to go?
Thanks for any help!
I would suggest subtracting the sold items right away from Product::available_items. This would resolve the issue right away, because Product::available_items would always reflect the number of available items.
Method no. 1
Subtract Sale::quantity from Product right away.
public function setProduct(ProductInterface $product)
{
$new_count = $product->getAvailableItems() - $this->getQuantity();
$product->setAvailableItems($new_count);
$this->product = $product;
}
You'd also have to do the subtracting in all the controllers that might change the available item count.
Method no. 2
Personally, I would actually favor this method over the first one, because it keeps the logic in a single place and generally results in shorter controllers. In addition, my entities are usually long enough without all the domain logic.
Assuming Sale has a reference to a Product, I'd put the logic into a service (an entity-specific entitymanager, e.g UserManager. It'd be called SaleManager in our case). The method in it would look something similar to:
public function updateSale(SaleInterface $sale, $flush = true)
{
$product = $sale->getProduct();
$new_count = $product->getAvailableItems() - $sale->getQuantity();
if ($new_count < 0) {
throw new NegativeQuantityException();
}
$product->setAvailableItems($new_count);
$this->em->persist($sale);
if (true === $flush) {
$this->em->flush();
}
}
I didn't touch the issue of what would happen if you were to remove a Sale from a Product or switch a Product in a sale, but you must certainly consider this as well.
Where do I place this method?
Consider creating a ProductSalesManager service into which you inject the entity manager. From a controller you would have something like:
$productSalesManager = $this->get(product_sales.manager);
$products = $productSalesManager->getProductsWithAvailableQuantity();
Now you can put your logic in the manager without worrying about which repository it happens to be in. It also decouples your controller from Doctrine itself.
And I'm not so sure maintaining current inventory in the product itself is such a good idea but that is really up to you.
As the available quantity bellows to the Product, I think the work has to be done by the Product Entity.
If you use Doctrine, it has generated the function addSale in your Product Entity ( the name depend on how you define the relation). I should change this function to make the calculation.
Assuming the field in your product entity is named available_quantity and the field in your Sale Entity is named items_number:
public function addSale ( $sale )
{
$this->setAvailableQuantity($this->getAvailableQuantity() - $sale->getItemsNumber());
$this->sales[] = $sale;
}
Then in your controller you add the sale to the product:
// get the product
$product = $this->getDoctrine()
->getRepository('AcmeStoreBundle:Product')
->find($id);
// build your Sale object
$sale = new Sale();
...
// add it to the product
$product->addSale($sale);
// save all
$em = $this->getDoctrine()->getEntityManager();
$em->persist($sale);
$em->persist($product);
$em->flush();
In your template you can get the available quantity of your product:
{{ product.availableQuantity }}
I have a Product object that has many InventoryCurrent objects. Once a month all inventory transactions will be summed and a new InventoryCurrent record will be created for each product in each warehouse. This is done so that the system does not have to do hundreds of calculations every time current inventory is requested.
I have created a from_warehouse scope as follows:
scope :from_warehouse, lambda {|warehouse| where(:warehouse_id =>warehouse) }
I would like to make a call to get the current inventory as follows:
product.current_inventories.from_warehouse(2).recent
This should return either the most current InventoryCurrent, or if one hasn't been created yet (because the product was just added) then it should return a new InventoryCurrent object with the proper warehouse_id and product_id set.
The problem is that scope returns a recordset, not a single object. I can't put this scope in a method and call .first because that might generate an error if the recordset is empty.
Any suggestions?
use find_or_create_by_warehouse_id_and_product_id, or find_or_initialize_by_warehouse_id_and_product_id. see this for more information.