Kohana ORM table join - join

I have 2 tables
user (id, name, position_id)
position (id, name)
how can i join the to models, so i can do something like this.
ORM::factory('user')->position()->name

See http://kohanaframework.org/3.3/guide-api/ORM#property:_belongs_to
class Model_User extends ORM {
protected $_belongs_to = array(
'position' => array('model' => 'Position')
);
}
Now you can:
ORM::factory('User')->with('postion')->find()->position->name;
Or indeed, with an already loaded user (e.g. $user = ORM::factory('User', 1);
$user->position->name;

Related

Manual SQL Query from Form Type / Abstract Class

First of all, I am moving from Symfony 1.4 to Symfony 3. (Yes, I was kicking and screaming at first)
My Question: I am running a manual query from the following FormType class that is for a chunk of my Signup form. I am moving the Address part of the signup into its own class. I am calling a geographical table to get my states list and I have a Union... hence this is why I am not calling an entity class.
The problem is that I need to connect to the database but cannot because it's an Abstract class. If I run this in the Controller Class, no problem, but can't do it herein this Abstract class. I have a bunch of manual steps to go through before making any inserts, so I can just
How do you make the following work? I have not created any services, but if I put all of this into a controller class, then it works fine.
<?php
namespace LocationBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Doctrine\ORM\EntityManager;
class PartialAddressType extends AbstractType
{
private function getStatesList()
{
$sql = "
SELECT
'0' AS id
,'' AS name
,'' AS abbreviation
,'Select State' AS display
UNION
SELECT
id
,trim(name)
,trim(abbreviation)
,CONCAT(trim(abbreviation), ' - ', trim(name)) AS display
FROM
geo_state
WHERE
type = 'state'
ORDER BY abbreviation ASC; ";
$manager = $this->getDoctrine()->getManager('default');
$conn = $manager->getConnection();
$rs = $conn->query($sql)->fetchAll();
return $rs;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$rs = $this->getStatesList();
// This one is for a Select
$builder->add('locationState', ChoiceType::class, array(
'expanded' => FALSE,
'multiple' => FALSE,
'choices' => $rs(),
'choice_label' => $rs['display'],
'choice_attribute' => $rs['abbreviation'],
'preferred_choices' => array('TX'),
'choices_as_values' => FALSE,
'label' => 'State',
)
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array());
}
public function getName()
{
return 'location_bundle_partial_address_type';
}
}
I suggest you following steps:
1) Move the query in a separate repository class (I hope you map the table as an entity)
2) Use an EntityType Field with the Custom query as described here
3) Avoid the UNION using the placeholder
Last tips, You should implements the getBlockPrefix method instead of getName as described in the migration guide here.
Hope this help

how to apply inner join in entityframework LINQ method syntax?

How to apply this query in entity framework method syntax
select company_id, country_id from companies, departments where companies.company_id == departments.company_id and department.departmentId = 10;
So far, I have:
var company = context.companies
.Where(com => com.Departments
.Contains(context.departments
.Where(dep => dep.department_id==_user.Department)
.FirstOrDefault()
)
)
.Select(com => new { com.company_id, com.Country })
.FirstOrDefault();
Using method based syntax, this could be as simple as;
var company = context.Companies
.Where(x => x.Departments
.Any(x => x.department_id == _user.Department)
)
.Select(x => new { x.company_id, x.Country });
This assumes your tables are set up with foreign keys giving each Company a list of Department objects. It very much depends on your data structure.

Querying Many to Many and Conditional Where

Within my Context file, I set up a many to many relationship between my Location class and Program class.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Location>()
.HasMany(u => u.Programs)
.WithMany(r => r.Locations)
.Map(m =>
{
m.ToTable("LocationsPrograms");
m.MapLeftKey("LocationId");
m.MapRightKey("ProgramId");
});
}
I'm creating a search/filter form where the user will need to be able to filter the locations by selecting a program.
My thought was to query the junction (M2M) table and then join that back up with the locations table.
The problem is that I don't have a class representing the M2M table other than in my OnModelCreating method.
Can I get an example on how to do this?
Basically select * from locations l join locationsprograms lp on l.LocationId = lp.locationid and lp.programid = whatever was passed in.
Thank you.
var locations = dbContext.Locations
.Where(l => l.Programs.Any(p => p.ProgramId == whateverWasPassedInId))
.ToList();
Or (works because your are filtering by the primary key property of Program):
var locations = dbContext.Programs
.Where(p => p.ProgramId == whateverWasPassedInId)
.Select(p => p.Locations)
.SingleOrDefault();

sfDoctrineGuardPlugin and admin filters

I have an admin that uses sfDoctrineGuardPlugin. I also have another table, sf_guard_user_profile, that extends the sf_guard_user table, to include more fields, such as address, age etc
My problem is, I am embedding the profile (sf_guard_user_profile) information into the sf_guard_user record when viewing the records in the admin generated module. This works fine, but I'd like to then be able to use some of the filters from the sf_guard_user_profile table.
I have tried to add these into the generator.yml file, but I this throws an error
generator.yml
...................
filter:
display: [username, email_address, address_1, is_active ]
Widget "address_1" does not exist.
address_1 is a field in sf_guard_user_profile
Is this possible to do?
Thanks
Ok, so I had to do a little bit of work in the sfGuardUserFormFilter class,
$this->widgetSchema['age'] = new sfWidgetFormInputText(array(
'label' => 'Age'
));
//Type of validator for filter
$this->validatorSchema['age'] = new sfValidatorPass(array ('required' => false));
public function getFields()
{
$fields = parent::getFields();
$fields['age'] = 'age';
return $fields;
}
public function addAgeColumnQuery($query, $field, $value)
{
$rootAlias = $query->getRootAlias();
$query->where('p.age LIKE ?', '%'.$value.'%');
//remember to return the $query!
return $query;
}
I could then use the age field in the generator.yml file.
Thanks

How to update many to many navigation property only?

i can update some properties use under method
public void Update(T entity, params Expression<Func<T, object>>[] properties)
{
_dbSet.Attach(entity);
DbEntityEntry<T> entry = _context.Entry(entity);
foreach (var selector in properties) { entry.Property(selector).IsModified = true; }
}
//repo.Update(entity, e => e.Name, e => e.Description);
but,i want to update navigation property only in many to many relationship
such like admin role adminrole i want to update adminrole table only
If you want to update just relation you can use simple tricks.
To add a new relation between admin and role you need to do:
Admin admin = new Admin { Id = adminId };
context.Admins.Attach(admin);
Role role = new Role { Id = roleId };
context.Roles.Attach(role);
// Create new relation on attached entities
admin.Roles.Add(role);
context.SaveChanges();
To remove existing relation between admin and role you can try this:
Admin admin = new Admin { Id = adminId };
Role role = new Role { Id = roleId };
// Simulate existing relation on detached entities
admin.Roles.Add(role);
context.Admins.Attach(admin);
// Remove existing relation on attached entities
admin.Roles.Remove(role);
context.SaveChanges();
In both scenarios you just need to know keys for admin and role.
Note: This is for scenario where you have real many-to-many (with junction table containing only keys).

Resources