Saving table relationships with Datamapper ORM - codeigniter

I am new to Object Model Mapping and just read the documentation of the CodeIgniter DataMapper. I have tried the examples and I am quite impressed in how little time one can achive a lot.
But I don't seem to get one problem solved:
Lets say I have two tables: customer and address. A customer can have many addresses but am address only one customer.
Now, I have a registration form where a new customer has to enter his personal data which is stored in the customer table and his address which is stored in the address table.
Validation is done in the specific models. My problem is how can I ensure that the data is valid for both tables prior to saving them to database.
At the moment it is possible that the customer enters the correct data for the customer table which validates and gets saved to db but the address data does not validate and is not saved.
In short: I only want to save the data of any table to db if the data for all tables validates else I want to get the error messages.
Thanks for any help in advance.

First way is to use transactions, second - validate both address and customer data, and if both is valid - store.

It's not clear from the documentation, but you can call the validate() method prior to calling save():
public function test()
{
// Customers require an email address
$cust = new Customer();
$cust->first_name = "Me";
$cust->validate();
if ($cust->error->string)
{
echo $cust->error->string;
// outputs The Email Address field is required.
}
else
{
// validation passed, save customer and related address to db
$cust->save(array($address));
}
}

If you have validation rules defined, you don't need to explicitly call validate(), the validation rules will also be checked when you call save().
In case validation failed, save() will return FALSE, after which you can check $this->valid to see if a validation error caused the save to fail.

Related

How to use same model with less fields for another view in mvc5

My Question is not belonging to how to use two models on same razor view ! basically I have a user table in which i have fields like(userid,name,email,password,gender,country,department,IsActive) and my form is working fine i am able to insert update and delete i have not use EF , what i did i create the table in sql server and create the model in my model folder , in my view i have put the required field validator for all these columns and they are mandatory to input while inserting or updating.
Now I want to have another view with another controller where i do not want to show all 8 fields instead want to show just these four columns( username,email,gender,IsActive)
when i am using the same model for the other controller and view then it loads the record correctly on index view ,but when i update the required it fires validation error as all my fields are mark as required so it ask to input the rest of four fields value as well.
I have tried to remove these un-necessary fields from model in controller code before saving using Bind([Exclude]"""") but it did not work.
I have tried modelstate.remove("") this approach works fine for all fields but my password field is still throwing validation error . someone says you need to use viewmodel and in viewmodel you have to put both of your model like the full model and small model, I want to ask how my small model would be mapped to my user table (as table["tableName"] this cannot be applied to two models and pointing to same table without primary foriegn key relation .
Share example please i am confused
modelState.Remove("Password")
This remove all model values which are un-necessary but not removing the password field which gives error while updating the
You have required fields missing data or some fields are not null when being saved. What you are trying to do is completely ok. You are basically using a Virtual Model. This is what I do. In the "get", you fix your model and send it to the view. You work with it and then when you submit, you receive the model in the "post", but it is missing several REQUIRED fields. So what you need to do is, retrieve the same record from the database, update the 3 or 4 fields from the view model and then save that model that you retrieved with the new data. This is one way. (VM = view model)
1. send VM to view
2. add data in the view
3. submit
4. receive VM in POST Controller
5. get same record from DB
6. update the particular fields using the VM data
7. save the updated record to database. This is the record you retrieved in 5.
Another way is to have all the missing fields in the model but not showing them in the view. However you need to mention them in the view, otherwise they will not post. so you need to use
#Html.Hidefor( x=> x.NameOfField)
This will ensure that the field is sent back for posting. Any field with a [Required]... is required. You cannot miss it!
How will your small model be mapped to the Database. It will not. You will transfer the data from the small model to the model that is mapped in the database... with ALL the fields. Either you get the missing values from the database or from the view by using Hidefor.
example
dbmodel.Field1 = vm.field1;
dbmodel.Field2 = vm.field2;
dbmodel.Field3 = vm.field3;
I hope this helps

Validation function to ensure unique field in couchdb

Is it possible to write a validation function to ensure a field of a new document is unique?
Imagine I'm trying to write a validation function that does not allow for two users to have the same email. Every time I create a new user, the validation function will be called and will probably look something like this:
function (newDoc, oldDoc) {
//How do I get this array to contain the emails of all the users?
var allEmail;
if (allEmail.indexOf(newDoc.email) !== -1) {
throw "This email adress is already taken";
}
};
How can I fill the array allEmail to contain all emails of the users?
Is it possible to call views in the validation function?
Not possible. Validation function only operates with updated doc and his previous revision and it cannot access to other documents. The only field that guaranteed to be unique is document _id. If it's possible and doesn't produce security/privacy issues, use email as doc _id to be ensure that it's unique.
Otherwise you have to create a view with target field as a key and check for it existence first before create a new doc on the client side. However, this logic easily becomes ruined when you'll replicate docs from other instance.
If the application is in offline, the above suggested solution how will react. Local pouch view can check and return the pouch results alone. There may be a high chance of same value entered from some other end and updated to couch db.
Do you have workaround for this case ?

A panoply of queries about Magento databases

Through which file are new customers created and saved in Magento databases?
Which function is used?
Please provide me with full path locations and function names.
Also tell me about customer groups. From where and through which files/functions do customer groups get saved in Magento?
How are customers and customer groups related?
How can I "catch" customer IDs and customer group IDs from those files?
I find the file through which Magento saves New Customer-:
/magento/app/code/core/Mage/Adminhtml/controllers/CustomerController.php
In the file CustomerController.php, there is a function saveAction() which saves a customer in Magento db.
I wanted to know how to catch Newly created customer's id(I guesss i.e. Entity Id in Customer_entity table for Magento db) from that CustomerController.php file.
I tried this but it won't work for me-"
$customer_data = Mage::getModel('customer/customer')->load($customer_id);
Anybody knows how to catch customer id while creation of new customer???
Try to search here:
Mage_Customer_AccountController->createPostAction
Well class name means
(root)/app/code/core/Mage/Customer/controllers/AccountControlller
Mage_Adminhtml_Customer_GroupController
Take a look at the AccountController.php at app/code/core/Mage/Customer/controllers, it will give you an idea how customer registration is processed.
Basically an instance of Mage_Customer_Model_Customer is created, proper data is assigned to it (collected from a post form on the registraton form or received via a webservice call) and the model is saved. The internal Magento mechanics work to put this data in proper db tables.
See also create function of the Mage_Customer_Model_Customer_Api class.
customer groups are created in Mage_Adminhtml_Customer_GroupController->saveAction(), the model being used is Mage_Customer_Model_Group
actually customer group is assigned from backend,by default general group is selected for customer group, if you want to get customer groups then you can use this code Mage::helper('customer')->getGroups()->toOptionArray();
Search for this file
/YourProject/app/code/core/Mage/Customer/controllers/AccountController.php
Search for this function name
public function createPostAction() //Magento saves New Customer
This above mentioned function is responsible for new customer registration.
print_r($this->getRequest()->getPost()); //get all the post data
print_r($session); //get all the session data

Validating unique field with HABTM join table

I'm struggling to work out how to validate a field in Model A that should be unique when combined with a field from Model B.
Here's an example to clarify my question:
Page hasMany SitesPage
SitesPage belongsTo Page, belongsTo Site
Page has a slug field which should be unique across a site. Pages can be attached to any site.
Page.id
Page.slug
SitesPage.id
SitesPage.site_id
SitesPage.page_id
I have a checkUniqueSlug() custom validation method in my Page model but can't validate the slug is unique to the site as the site_id is stored in SitesPage which isn't available in the Page model validate method ($this->data only contains Page model data).
I can't do the validation in the SitesPage model as SitesPage doesn't have a slug field and I can't see the Page post is SitesPage.
How do I create a custom validation to check the slug is unique to the site?
One solution is to move the slug into the SitesPage model but we need all shared pages to have the same slug. i.e. A shared "About Us" page must have an "about_us" slug irrespective of which site the page is attached to.
Another solution is to perform the validation in the controller before I save which would work but that feels wrong as the validation should be done in the model.
As there have been no answers and someone else might be looking for help, here's how I ended up with a solution:
As the controller is the only place where both model data is present in the data array, the call to validate has to be done there.
I offloaded the validation code to the model and called it with the following:
if (!empty($this->request->data)) {
if ($this->Model->specialMultiModelValidate($this->request->data) && $this->Model->save($this->request->data)) {
// model has validated and saved
}
else {
// model has failed to validate and save
  }
}
Hope someone finds this useful.

Magento - custom form

I have a form, which at the moment is a simple HTML based one, that doesn't do anything.
What I'm looking to do though, is to be able to send an email once the form has been submitted and also save the data to the database.
The problem comes, with the email sending. In the form, there is a drop down menu. The menu items are items in my suppliers model/module, which have a name and email address.
So, when I select Supplier A, the form passes validation, it needs to send Supplier A an email and save the details (this shouldn't be too hard).
I'm just not sure how I'd get the email address.
Would I need to pass some kind of parameter to a custom sendEmail() method?
All help appreciated.
Thanks
UPDATE:
Ok, so before I do the email part, I'd like to store the data in the table, named test drive.
I've created the module in the admin and a form to submit data from on the frontend end.
But I cannot seem to get the data to insert.
All help is welcome
Thanks
For sending email see this Mage_Contacts_IndexController::postAction() action or
Mage_Sales_Model_Order::sendNewOrderEmail()
If You created module with model, you can get instance of that model, insert data and then save it or You can create ResourceModel and then execute SQL.

Resources