Laravel 5 where子句来自另一个表

时间:2015-10-29 01:36:20

标签: php laravel laravel-5 eloquent

我有一个简单的代码,我想要做的是从另一个表访问一个字段并将其放在我的where子句中。这是我的代码:

ReportController.php

import requests, re
from xml.etree import ElementTree
from collections import Counter

def main(n=10):

    # A list of feeds to process and their xpath
    feeds = [
        {'url': 'http://www.nyartbeat.com/list/event_type_print_painting.en.xml', 'xpath': './/Description'},
        {'url': 'http://feeds.feedburner.com/FriezeMagazineUniversal?format=xml', 'xpath': './/description'},
        {'url': 'http://www.artandeducation.net/category/announcement/feed/', 'xpath': './/description'},
        {'url': 'http://www.blouinartinfo.com/rss/visual-arts.xml', 'xpath': './/description'},
        {'url': 'http://www.art-agenda.com/category/reviews/feed/', 'xpath': './/description'}
    ]

    # A place to hold all feed results
    results = []

    # Loop all the feeds
    for feed in feeds:
        # Append feed results together
        results = results + process(feed['url'], feed['xpath'])

    # Join all results into a big string
    contents=",".join(map(str, results))

    # Remove double+ spaces
    contents = re.sub('\s+', ' ', contents)

    # Remove everything that is not a character or whitespace
    contents = re.sub('[^A-Za-z ]+', '', contents)

    # Create a list of lower case words that are at least 6 characters
    words=[w.lower() for w in contents.split() if len(w) >=6 ]

    # Count the words
    word_count = Counter(words)

    # Clean the content a little
    filter_words = ['artist', 'artists']
    for word in filter_words:
        if word in word_count:
            del word_count[word]

    # And the survey says...
    print("The Top {0} words".format(n))
    for word, count in word_count.most_common(n):
        print("{0}: {1}".format(word, count))

def process(url, xpath):
    """
    Downloads a feed url and extracts the results with a variable path
    :param url: string
    :param xpath: string
    :return: list
    """
    contents = requests.get(url)
    root = ElementTree.fromstring(contents.content)
    return [element.text.encode('utf8') if element.text is not None else '' for element in root.findall(xpath)]

if __name__ == "__main__":
    main()

Room.php

$reservations = Reservation::with('charge', 'room', 'client')
-> whereBetween('reservation_from', [$from, $to])
-> where('room.type', \Request::input('type')) //what should this be
-> orderBy('created_at')
-> get();

Reservation.php

class Room extends Model
{
    use SoftDeletes;
    protected $table = 'rooms';

    protected $fillable = ['id', 'roomNumber', 'type', 'price', 'description'];

    public function reservations() {
        return $this->hasMany('App\Reservation', 'id', 'room_number');
    }
}

架构: enter image description here

正如您在class Reservation extends Model { use SoftDeletes; protected $table = 'reservations'; protected $fillable = ['roomNumber', 'clientId', 'reservation_from', 'reservation_to']; public function room() { return $this->belongsTo('App\Room'); } } 中所看到的,有一条评论说“这应该是什么”,这是我想要修复的部分。我想要做的是在我的雄辩查询中访问房间表中的ReportController.php字段。

我想要做的查询是这样的:

type

有办法做到这一点吗?谢谢。

2 个答案:

答案 0 :(得分:9)

您正在寻找的是whereHas方法。

$reservations = Reservation::with('charge', 'room', 'client')
    ->whereBetween('reservation_from', [$from, $to])
    ->whereHas('room', function($query) {
        $query->where('type', '=', \Request::input('type'));
    })
    ->orderBy('created_at')
    ->get();

链接到文档:http://laravel.com/docs/5.1/eloquent-relationships#querying-relations

编辑:

编辑此内容以澄清评论中的一些内容。

要创建方便,可重复使用的查询约束以使代码更清晰,您可以使用查询约束:http://laravel.com/docs/5.1/eloquent#query-scopes

此外,由于查询可以链接,您可以执行以下操作:

// Create query with common constraints
$query = Reservation::with('charge', 'room', 'client')
    ->whereBetween('reservation_from', [$from, $to]);

// Ternary operator to decide whether or not to add whereHas constraint
$query = (\Request::input('type') == "all") ? $query : $query->whereHas('room', function($query) {
    $query->where('type', '=', \Request::input('type'));
});

// Finally, fetch the results sorted by 'latest', which is a convenient way of doing "orderBy('created')"
$reservations = $query->latest()->get();

答案 1 :(得分:2)

我相信你是想做到这一点的。根据您的问题更新更新。 with方法采用字符串或数组。

$reservations = Reservation::with(['charge', 'client', 'room' =>   
    function($query){
        $query->where('type', \Request::input('type'));
    }])
->whereBetween('reservation_from', [$from, $to])
->orderBy('created_at')
->get();