Laravel 实战开发知乎:实现选择话题整个流程
打赏作者

wenjie_zheng

如果用户的自定义话题填写的是 数字 怎么来判断?通过去查询数据库来判断?

JellyBool 回复 wenjie_zheng

你可以把所有 topics id 拿出来,再判断一下有没有这个数字就行

wenjie_zheng 回复 JellyBool

好主意,,,

zddragon 回复 JellyBool

Laravel 实战开发知乎,这个系列视频大概有多少节?

JellyBool 回复 zddragon

应该很多,36节以上吧。。不过过年前打算更完

zddragon 回复 JellyBool

现在不能单独订阅这个系列的视频吗?

JellyBool 回复 zddragon

恩,单独的已经关闭很久了

hao0661

代码的颜色很舒服,能分享一下吗?

laravistpublic

获取特定资源的关联模型的话我觉得这样写更好点:

$question = Question::with('topics')->findOrFail($id);

JellyBool 回复 laravistpublic

好的,我学习一个

xshaitt 回复 JellyBool
$question = Question::findOrFail($id);

您好请问这样写和上面有什么差别么?
最终在view里还是一样输出

JellyBool 回复 xshaitt

findOrFail 没找到的时候会抛出 ModelNotFoundException

xshaitt 回复 JellyBool

我的意思是加with和不加with,好像没差别额,在view中还是会调用topics关系

JellyBool 回复 xshaitt

额。。不太明白你的意思,不是会,是可以吧

你传入一个数据库不存在的 id 试试就知道了

xshaitt 回复 JellyBool

findOrFail这个我是理解的,我是这两段代码

$question = Question::with('topics')->findOrFail($id);
$question = Question::findOrFail($id);

都是返回一个Collection,但是加with的Colletion中的relations是有关联数据的,没加的是没有的,但是在view中都是这样调用

$question->topics

因为加和没加都是正常实现功能的,
so,我对这个不太理解,加这个with的作用是什么
我这样描述会不会清晰点

JellyBool 回复 xshaitt

with 是懒加载,提前把数据查找出来了,不会出现 n+1 的问题

没有使用 with 的时候,你也可以使用 question->topic 只不过这是执行一次查询

hard88

你好,我在添加了question>topics()>attach(question->topics()->attach(topics);语句后报错:
QueryException in Connection.php line 770:
SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘question_id’ in ‘field list’ (SQL: insert into question_topic (created_at, question_id, topic_id, updated_at) values (2017-02-27 20:03:20, 7, 13, 2017-02-27 20:03:20), (2017-02-27 20:03:20, 7, 2, 2017-02-27 20:03:20))

JellyBool 回复 hard88

你的关联表 question_topic 没有 question_id 这个字段吧,跟视频来吧

hard88 回复 JellyBool

有。。我还重新生成了一遍这个表,刚又检查了一遍发现question_id这个字段 写成了queistion_id。。这种问题真的,麻烦了

lg23

http://www.zt.com/questions/2
浏览器输入上面内容时,出现下面报错:
Call to undefined relationship [topics] on model [App\Models\Question].
检查控制器及model没发现问题
Question model

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Question extends Model
{
    protected $fillable = ['title', 'body', 'user_id'];

    /**
     * 定义多对多关系
     */
    public function topics()
    {
    	return $this->belogsToMany(Topic::class)->withTimestamps();
    }
}

QuestionsController 控制器

public function show($id)
    {
        // 使用 with 方法指定想要预载入的关联对象 预载入可以大大提高程序的性能
        // 这里的 topics 是App\Models\Question 中的 topics 的方法
        $question = Question::where('id',$id)->with('topics')->get();

        // compact 创建一个包含变量名和它们的值的数组
        return view('questions.show',compact('question'));
    }
JellyBool 回复 lg23

看不出有什么错误。。。
试试这样?

Question::with('topics')->where('id',$id)

所以你还是照你的想法来学?

lg23 回复 JellyBool

Question::where(‘id’,$id)->first();
这 样是没有问题的
其实很多东西我都学过,只是理解不深刻或是没记住。我会抓紧时间看群主的视频,比我以前学习的例子好很多。

lg23 回复 JellyBool
public function topics()
    {
    	return $this->belongsToMany('App\Models\Topic')->withTimestamps();
    }

这里有问题,我至于具体是哪?我也不知道,我从文档中复制了这句就对了?
当然 Topic::calss 也是正确的

hmengpang 回复 lg23

model的namespace错了。。。应该是App,

hmengpang

已解决。。是自己犯傻。。不好意思。。

tophgg

大佬,问一下 跟着视频步骤做点击“提交” 在show方法里输出dd($request->get(‘topics’));
可是我自从加了话题之后,点击“提交”之后只会在原页面刷新了一次,跳转不到show方法里面去
然后我试了下把

 public function store(StoreQuestionRequest $request) // 依赖注入

里的StoreQuestionRequest改回Request之后 又可以跳转了,没加话题之前是可以正常提交的 这是什么原因呢? 是我漏改了吗

JellyBool 回复 tophgg

StoreQuestionRequest 里面的 rules 验证没通过,或者你的 authorized 方面没改对

tophgg 回复 JellyBool

试了一下,原来rules返回的数组里最后多了个逗号就会这样 去掉之后ok了 谢啦

xiaofengzhi

谁有那个class = topic的css样式?

北漂张小白
public function normalizeTopic(array $topics)
{

    return collect($topics)->map(function ($topic) {
        if ( is_numeric($topic) ) {
            Topic::find($topic)->increment('questions_count');
            return (int) $topic;
        }
        $newTopic = Topic::create(['name' => $topic, 'questions_count' => 1]);
        return $newTopic->id;
    })->toArray();
}


这个是什么意思,不太明白,主要是collect($topics)->map...是什么作用不太理解,之前有在哪里讲到吗??
JellyBool 回复 北漂张小白

你看看 colletion 重构代码那个系列

北漂张小白 回复 JellyBool

好的,谢谢!!

Smile雨后21

防止数字标签
防止重复创建标签(输入已有标签,不选提示框里的直接回车,会建立重复标签)

    private function normalizeTopic(array $topics)
    {
        $ids = Topic::pluck('id');

        $ids = collect($topics)->map(function ($topic) use ($ids) {
            if (is_numeric($topic) && $ids->contains($topic)) {
                return (int) $topic;
            }

            return Topic::firstOrCreate(['name' => $topic])->id;
        })->toArray();

        Topic::whereIn('id', $ids)->increment('questions_count');
        return $ids;
    }
JellyBool 回复 Smile雨后21

阔以阔以!!

xshaitt 回复 JellyBool

还是可以数字标签插入的。

Perfect丶戈 回复 Smile雨后21

赞,不过我这里效果不会车他不会把值传过来

noikiy 回复 Smile雨后21

阔以!!!!!

xshaitt 回复 Smile雨后21

pluck()方法干嘛的

a4922291

Jelly select选项框我name也添加进去了,但是提交后一直拿不到topics的值,显示为空。我查了以后提示store方法中$request 参数类型不对,不知道是什么情况

JellyBool 回复 a4922291

具体是什么类型不对?可以把相关的代码都贴出来么?

a4922291

问题已解决,是浏览器缓存问题,我加了name,但是缓存一直没清掉 尴尬~~~~~

JellyBool 回复 a4922291

OK。。问题解决了就好。这些都是经验值的加成

a4922291 回复 JellyBool

恩恩,都是经验值,JellyBool有出商城类的项目或者打算出吗?这个项目学到很多,想再学学商城类的

Jiyao

请问视频里1:12秒那儿添加方法的操作是什么啊?是快捷键么?找了半天没找到~~

zhouxiaoshuai3 回复 Jiyao

win下 Ctrl+Shift+a 然后输入 add method 、mac 下 command+Shift+a 然后 add method 。你试下

foxriver123

public function normalizeTopics(array topics){ return collect(topics)->map( function($topic){

        if(is_numeric($topic) && $topic_number = (int)$topic){
            if( $newTopic = Topic::find($topic_number) ){
                $newTopic->increment('questions_count');
                return $topic_number;
            }
            
        }

        if($newTopic = Topic::where('name',$topic)->first()){
            $newTopic->increment('questions_count');
            return $newTopic->id;
        }
        
        $newTopic = Topic::create(['name'=>$topic , 'questions_count'=>1]);
        return $newTopic->id;
    })->toArray();
}

解决All

Flourishing 回复 foxriver123

6666666 写的很好

blaze0207

請問大大一下,我跟著教學做到多對多關係這步驟,出現了如下圖的錯誤:
錯誤顯示

可是我有跟著教學先 dd($topics); 也的確有值不是 null,如下圖所示:
topics的值

我是用 laravel 5.5 版本,可以請教錯誤在哪嗎?
看了很多遍找不出原因~!
謝謝

#找到原因了,我在 model 裡的 TopicQuestion,多對多的 function 都忘了 return,導致一直找不到所以才會顯示 null,犯了低級錯誤XD~~!

liujun

laravel5.6版本:
在show方法中用关联模型直接传递给视图,在视图中如下操作
@foreach($question->topics as $topic)

@endforeach
这样的话是不是没有执行预加载,导致n+1查询呢?

JellyBool 回复 liujun

嗯,你需要的是使用 with 加载