PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label model-associations. Show all posts
Showing posts with label model-associations. Show all posts

Friday, October 21, 2022

[FIXED] how to associate two models using has_many and belongs_to ruby on rails

 October 21, 2022     belongs-to, has-many, model-associations, ruby, ruby-on-rails     No comments   

Issue

I have generated two models tour and tourcategories in my application. Now I want to associate these two models using has_many and belongs_to. Where tour can relate with single tourcategory but tourcategory can have more than one tours. So definition of the tour model is following:

class Tour < ActiveRecord::Base
  belongs_to :tourcategory
  attr_accessible :content, :element_id, :job_id, :title, :priority, :tourcategory
end

this is the definition of tourcategory model:

class Tourcategory < ActiveRecord::Base
  has_many :tours
  attr_accessible :title
end

this is the definition of the tours migration file: class CreateTours < ActiveRecord::Migration

def change
    create_table :tours do |t|
      t.string :element_id
      t.string :title
      t.text :content
      t.integer :job_id
      t.integer :priority
      t.belongs_to :tourcategory, index:true
      t.timestamps
    end
  end
end

this is the definition of the tours controller :

def new
        @tourcategories = Tourcategory.all
        @tour = Tour.new
        @tour.build_tour
        respond_to do |format|
        format.html
        format.json { render json: @tour }
        end
    end

Now I am getting an error

undefined method `tourcategories'

When I access the _form.html.haml view for editing and for adding new tour. this the code where error is encountered.

.field
    = label_tag "tour Categories"
    %br/
    = select_tag "tourcategory", options_from_collection_for_select(Tourcategory.all, 'id', 'title', @tour.tourcategories.map{ |j| j.id })
    = f.submit

Solution

You actually need to use HABTM (Has And Belongs To Many) - please check out Rails documentation for more details



Answered By - SpeedyWizard
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to correctly apply a has_many relationship with an order by in Ruby on Rails 6

 October 21, 2022     associations, has-many, model-associations, ruby-on-rails, ruby-on-rails-6     No comments   

Issue

I am creating a User model in Rails 6 to mirror a model that exists in a separate project. There is a has_many relationship that is causing some problems.

class User < ApplicationRecord
      has_many :activation_histories, inverse_of: :user , => { order "created_at  DESC"} 
end

The project I am basing this on used Rails 3.2 and worked successfully like this

class User < ApplicationRecord
       has_many :activation_histories, inverse_of: :user, order: "created_at desc" 
end

I can see from the official documentation the example using an order by looks as so

class Author < ApplicationRecord
  has_many :books, -> { order "date_confirmed DESC" }
end

I get an error that it is expecting '=>' rather than '->' when I run it as so, but when I use '=>' I am getting

app/models/user.rb:6: syntax error, unexpected =>
app/models/user.rb:6: syntax error, unexpected '}', expecting `end'
app/models/user.rb:6: syntax error, unexpected =>
app/models/user.rb:6: syntax error, unexpected '}', expecting `end'
app/models/user.rb:6: syntax error, unexpected =>
app/models/user.rb:6: syntax error, unexpected '}', expecting `end'

I am relatively new to Ruby on Rails and am not sure where I am going wrong here or how to proceed. Removing the inverse_of has no effect on the errors I am seeing.

Any advice on how to correctly use this would be appreciated.


Solution

Try changing

has_many :activation_histories, inverse_of: :user , -> { order "created_at  DESC"} 

to

has_many :activation_histories, -> { order "created_at  DESC"} , inverse_of: :user

Your scope should be your second argument. https://www.rubydoc.info/docs/rails/4.1.7/ActiveRecord%2FAssociations%2FClassMethods:has_many



Answered By - RHFS
Answer Checked By - Clifford M. (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, March 18, 2022

[FIXED] Save data in a cakephp hasmany and belongsto association at once

 March 18, 2022     cakephp, cakephp-2.5, model-associations, php     No comments   

Issue

I know this question is asked here a many times but I also tried to follow the solutions provided at my best. As I am learning a cakephp some solutions seemed difficult to implement in a code. I am using cakephp 2.5.

What I am trying to do is creating a problem report with attached one or more uploads. Here is some of what I have implemented so far:-

I have following models:

  • Candidate
  • CandidatesProblemReport
  • CandidatesProblemReportsUpload

There associations are as follows:

  • CandidatesProblemReport hasMany CandidatesProblemReportsUpload

  • Candidate hasMany CandidatesProblemReport

  • CandidatesProblemReport belongsTo Candidate

  • CandidatesProblemReportsUpload belongsTo CandidatesProblemReport

Candidate.php

    <?php

    class Candidate extends AppModel {

        public $name = 'Candidate';
        public $hasMany = array(

            'CandidatesProblemReport' => array(
                'className' => 'CandidatesProblemReport',
                'foreignKey' => 'candidate_id'
            )

        );
    }

CandidatesProblemReport.php

    <?php

    class CandidatesProblemReport extends AppModel {

        public $name = "CandidatesProblemReport";
        public $belongsTo = array(
            'Candidate' => array(
                'className' => 'Candidate'
            )
        );
        public $hasMany = array(
            'Uploads' => array(
                'className' => 'CandidatesProblemReportsUpload'
            ),
            'Replies' => array(
                'className' => 'CandidatesProblemReportsReply'
            )
        );    
    }

CandidatesProblemReportsController.php

    class CandidatesProblemReportsController extends AppController {

        public $name = "CandidatesProblemReports";

        // ############# Report a Problem #############
        // ********************************************
        public function create() {
            $userid = $this->Auth->user('id'); // Grabs the current user id
            $this->set('userId', $userid); // Sends the current user id to the form

            if ($this->request->is('post') && !empty($this->request->data)):

                $this->CandidatesProblemReport->create();

                $report = $this->CandidatesProblemReport->save($this->request->data);
                if (!empty($report)):         
                    $this->request->data['CandidatesProblemReportsUpload']['candidates_problem_report_id'] = $this->CandidatesProblemReport->id;
                endif;

                if ($this->CandidatesProblemReport->saveAssociated($this->request->data)):

                    $this->Session->setFlash('Your report has been submitted '
                            . 'successfully. Thank you!');

                    $this->redirect(array(
                        'action' => 'viewall')
                    );
                else:
                    $this->Session->setFlash('Your report could not be submitted, '
                            . 'please try again');
                endif;

            endif;
        }
    }

create.ctp

<h1>Create a report</h1>
<?php
echo $this->Form->create('CandidatesProblemReport', array('type' => 'file'));

echo $this->Form->input('CandidatesProblemReport.report_subject');

echo $this->Form->input('CandidatesProblemReport.report_handle_department', array(
    'options' => array(
        'Technical' => 'Technical',
        'Sales' => 'Sales',
        'Support' => 'Support',
        'Other' => 'Other'
    )
));
echo $this->Form->input('CandidatesProblemReport.report_description');

echo $this->Form->input('CandidatesProblemReport.report_date', array(
    'type' => 'hidden',
    'value' => date('Y-m-d H:i:s'))
);

echo $this->Form->input('CandidatesProblemReport.candidate_id', array(
    'type' => 'hidden',
    'value' => $userId)
);
?>

<div>
    <p><strong>Upload Screenshot/Files</strong></p>
    <hr>
</div>
<?php
echo $this->Form->input('CandidatesProblemReportsUpload.0.report_upload', array(
    'type' => 'file'
));
?>
<button class="add-new-upload" type="button">Add more</button>
<?php
echo $this->Form->end('submit');

echo $this->Html->script('jquery-2.1.1.min.js');
?>

<script type="text/javascript">
    var i = 1;
    $('.add-new-upload').click(function () {
        $('.file').append('<input type="file" name="data[CandidatesProblemReportsUpload]['
                + i +
                '][report_upload]" id="CandidatesProblemReportsUpload'
                + i +
                'ReportUpload">');
        i++;
    });
</script>

Now what is happening is I am able to save the main model data i.e. CandidatesProblemReports but when I saveAssociated data it again saves the main model creating second duplicate entry but the uploads are not getting saved.


Solution

Saving data with associations

That's the expected behavior, saveAssociated() is not ment to save only the associated records, it will save the main record as well, so you should use saveAssociated() only, no need to manually set the foreign key, etc, CakePHP will do that automatically.

Controller

public function create() {
    // ...

    if ($this->request->is('post') && !empty($this->request->data)):

        $this->CandidatesProblemReport->create();

        if ($this->CandidatesProblemReport->saveAssociated($this->request->data)):
            // ...
        endif;

    endif;
}

Mind your aliases

The reason for your upload records not being created, is that you are not using the proper alias in your form/data, you've set the alias to be Uploads, but in your form you are using CandidatesProblemReportsUpload, and so CakePHP will ignore this data.

Form

echo $this->Form->input('Uploads.0.report_upload', array(
    'type' => 'file'
));
<script type="text/javascript">
    var i = 1;
    $('.add-new-upload').click(function () {
        $('.file').append('<input type="file" name="data[Uploads]['
                + i +
                '][report_upload]" id="Uploads'
                + i +
                'ReportUpload">');
        i++;
    });
</script>

Storing file data

As mentioned in the comments, CakePHP doesn't handle file upload data out of the box, you'll have to prepare it in beforehand so that it is for example being stored on disk, and the model stores the path to the file.

While the above code should generally work, it will most likely trigger an error as it will try to store the file upload array in the database instead of flat data.

There are plugins out there that can handle file uploads, check them out, also search here on stackoverflow and check the docs for examples on how to modify data before it is being saved.

For starters:

  • http://book.cakephp.org/2.0/en/models/callback-methods.html#beforesave
  • http://book.cakephp.org/2.0/en/models/callback-methods.html#beforevalidate
  • https://github.com/josegonzalez/cakephp-upload


Answered By - ndm
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, January 16, 2022

[FIXED] Find by conditions on associated model in CakePHP 3

 January 16, 2022     cakephp, cakephp-3.2, model-associations     No comments   

Issue

I have two tables orders and sub_orders. Their association is

$orders->hasMany('SubOrders', [
   'foreignKey' => 'order_id'
]);

Both tables have invoice_no and sub_invoice columns in orders and sub_orders respectively.

I have to find records from orders table containing associated sub_orders where $trackingId will match either Orders.invoice_no or SubOrders.sub_invoice

$findOrder = $this->Orders->find('all', [
    'conditions' => [
      'OR' => [
         'Orders.invoice_no' => $trackingId,
         'SubOrders.sub_invoice' => $trackingId
       ]
     ],
     'contain' => [
        'SubOrders'
     ]
  ]);

But this gives error

Column not found: 1054 Unknown column 'SubOrders.sub_invoice' in 'where clause'

Solution

Try doing the query like this:

$findOrder = $this->Orders->find()
->where(['Orders.invoice_no' => $trackingId])
->contain(['SubOrders' => function ($q) use ($trackingId) {
   return $q

        ->where(['SubOrders.sub_invoice' => $trackingId]);
}
]);


Answered By - Derek
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Cakephp 3.6 contain

 January 16, 2022     cakephp, cakephp-3.x, contain, model-associations, php     No comments   

Issue

I have on little problem with my Cakephp's project. I have this get function in StudentController for view action.

$student = $this->Students->get($id, [
        'contain' => ['Courses', 'LessonPresences', 'StudentNotes', 'StudentPayments']
    ]);

StudentNotes are added by Users. With the contain I get the StudentNotes with the ID of the user who add this note. How I can get the name of this user ?

Student {#711 ▼ 
+"id": 1
+"name": "John"
+"lastname": "Doe"
+"email": "johndoe@gmail.com"
+"phone": "111222333"
+"address": "Brown Street"
+"add_date": FrozenTime @1531866000 {#347 ▶}
+"sign_date": FrozenDate @1531699200 {#350 ▶}
+"theory_count": 65
+"course_end": null
+"course_id": 1
+"student_notes": array:1 [▼
0 => StudentNote {#607 ▼
  +"id": 1
  +"s_content": "Test student's note"
  +"add_date": FrozenTime @1532677715 {#606 ▶}
  +"student_id": 1
  +"add_user_id": 1

I have "add_user_id" which is "1". How can I get the name of this user? There is an belongsTo association in StudentNotesTable

$this->belongsTo('Users', [
        'foreignKey' => 'add_user_id',
        'joinType' => 'INNER'
    ]);

Solution

simply add 'Users' to the contain array. You can do it in many ways, the following are all equivalent

Using dotted notation

 'contain' => [
    'Courses', 
    'LessonPresences', 
    'StudentNotes', 
    'StudentNotes.Users',
    'StudentPayments',
 ]

Using array

 'contain' => [
    'Courses', 
    'LessonPresences', 
    'StudentNotes' => ['contain' => ['Users']], 
    'StudentPayments',
 ]

Using callable

 'contain' => [
    'Courses', 
    'LessonPresences', 
    'StudentNotes' => function ($q) {
         return $q->contain(['Users']);
    }, 
    'StudentPayments',
 ]


Answered By - arilia
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, January 10, 2022

[FIXED] Cakephp 3.0 Save associated model

 January 10, 2022     associated-object, cakephp, cakephp-3.0, model-associations, save     No comments   

Issue

I am learning cakePHP 3.0 and have some problem with saving associated data on my model.

I try to save a Client with associated data of ClientPreferences

ClientTable

class ClientsTable extends Table
{
    public function initialize(array $config)
    {
        (...)
        $this->belongsTo('ClientPreferences', [
            'foreignKey' => 'client_preferences_id'
        ]);
    }
}

ClientController

$aClient = $this->Clients->newEntity();
$aClient = $this->Clients->patchEntity($aClient, $this->request->data);

$aClientPreference = $this->Clients->ClientPreferences->newEntity();
$aClientPreference->my_field = 'my value';

$aClient->ClientPreferences = $aClientPreference;

$this->Clients->save($aClient, ['associated' => ['ClientPreferences']];

The Client entity is correctly saved, but not the associated ClientPreferences entity and there is no error thrown by Cake.

I have tried to follow this : http://book.cakephp.org/3.0/en/orm/saving-data.html#saving-with-associations

But haven't find any issue to do it properly. Do anybody have an advice ?

Thank you in advance.


Solution

Conventions, conventions, conventions

There's clearly a difference in the examples that you've linked, take a closer look at the property names, and if you scroll down a little further, you'll find an explanation specifically for belogsTo associations.

When saving belongsTo associations, the ORM expects a single nested entity at the singular, underscored version of the association name. For example: [...]

Cookbook > Saving Data > Saving BelongsTo Associations

So for belongsTo associations, the property name is by default expected to be lowercased and underscored, ie $aClient->client_preference.

Your foreign key should btw. be singular too in order to match the conventions, ie client_preference_id, even though it's just the property name causing the problem.

See also Cookbook > Associations > BelongsTo Associations (especially the foreignKey and propertyName options)



Answered By - ndm
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, January 1, 2022

[FIXED] Find by associated data on paginate

 January 01, 2022     cakephp, cakephp-3.0, model-associations     No comments   

Issue

I have two: Providers and Purchasetopay with the following association:

$Providers->hasMany('Purchasetopay', [
   'foreignKey' => 'providers_id'
]);

and I also have the following action:

public function fornecedores(){

        $Providers = TableRegistry::get('Providers');

        $pesquisar = $this->request->query('pesquisar');

        if(!empty($pesquisar)){
            $this->paginate = [
                'conditions' => 
                            [ 'OR' => 
                                ['Providers.cnpj' => $pesquisar,
                                 'Providers.corporatename LIKE' => '%'.$pesquisar.'%',
                                ]                              
                            ]
                         ];
        }

        $query = $Providers->find()->contain(['Telephones','Purchasetopay'=>['SupplierNotes']]);
        $providers = $this->paginate($query);
        $this->set(compact('providers'));

    }

I need to add Purchasetopay field to OR conditions. How? I saw this solution: https://stackoverflow.com/a/39559315/11239369 However, I don't know how to adapt my code to work this way.


Solution

You can use orWhere/andWhere as below :

$query = $Providers->find()
          ->contain(['Telephones','Purchasetopay'=>['SupplierNotes']])
          ->where( ['Providers.cnpj' => $pesquisar])
          ->orWhere(['Providers.corporatename LIKE' => '%'.$pesquisar.'%' ]);


Answered By - Shifat
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home
View mobile version

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing