【问题标题】:Rails 4 - how to write a scope to exclude one recordRails 4 - 如何编写范围以排除一条记录
【发布时间】:2016-08-15 02:04:33
【问题描述】:

我正在尝试学习如何在我的 Rails 4 应用程序中编写范围。

我有称为用户、配置文件、项目和潜在用途的模型。这些关联是:

用户

has_one :profile
has_many :potential_uses

简介

belongs_to :user
has_many :projects

项目

belongs_to :profile
has_many :potential_uses

潜在用途

belongs_to :project
belongs_to :user

我的潜在用途表中有以下属性:

:comment
:internal_comments_permitted
:external_comments_permitted

我的潜在用途模型中有以下范围:

scope :internal_comments_permitted, ->  where(:internal_comments_permitted => 'true')
    scope :external_comments_permitted, ->  where(:external_comments_permitted => 'true')

然后我有一个类方法来查找所有第三方 cmets:

def third_party_comments
  self.internal_comments_permitted.external_comments_permitted
end

现在,我正在尝试编写一个范围,以从第三方 cmets 组中排除拥有项目所属个人资料的用户所做的任何评论。

我想要一个视图页面,将第三方 cmets 与项目创建者的 cmets 分开显示。

scope :third_party_comments, -> where(:comment.user_id != potential_uses.project.profile.user_id)

我知道上面的说法不对,但我不知道这次尝试有什么问题。

在 Ninigi 的调整中采纳 Hasmukh 的建议:

scope :third_party_comments, ->(potential_uses.project.profile.user_id) { where.not(comments: {user_id: potential_uses.project.profile.user_id} ) }

但这给出了一个错误:

syntax error, unexpected '.', expecting ')'
...ty_comments, ->(potential_uses.project.profile.user_id) { wh...

【问题讨论】:

    标签: ruby-on-rails scope


    【解决方案1】:

    试试这个:

    scope :third_party_comments, ->where.not(comment.user_id: potential_uses.project.profile.user_id)
    

    参考:Active Record Query Interface

    【讨论】:

    • @Hasmukh_Rathod。谢谢你的建议。我试过这个,但它似乎在它的某个地方有一个错误:语法错误,意外的'。',期待keyword_do_LAMBDA或tLAMBEG ...third_party_cmets,-> where.not(comment.user_id:potentia ...
    • 你能看出有什么问题吗?我不知道 tLAMBEG 是什么意思
    • -> 和 where.not 子句之间不能有空格。我已经更新了我的答案。
    • 我也试过了。然后它给出一条错误消息:语法错误,意外'。',期待keyword_do_LAMBDA或tLAMBEG
    • @TarynEast - 语法错误,意外 ':' ...-> { where.not(comment.user_id: potential_uses.project.profi... ...
    【解决方案2】:

    你快到了。

    scope :third_party_comments, -> where(:comment.user_id != potential_uses.project.profile.user_id)
    

    where 接受一个散列或一个 SQL 片段数组,但你有一个条件代替。 所以你不能完全像上面那样做,但你可以使用 SQL 片段,例如尝试:

    scope :third_party_comments, -> { where("comment.user_id <> ?",  potential_uses.project.profile.user_id) }
    

    这使用 Rails 的数组语法 - 第一项是一小块纯 SQL - 它使用 &lt;&gt; 表示“不等于”并使用问号表示“第二个值在此处” (但以安全消毒的方式)

    注意:没有经过错误测试,可能需要一些小的调整才能使其正常工作...我会查看查询界面上的 Rails 指南以了解您可以做什么和不可以做什么的更多详细信息:http://guides.rubyonrails.org/active_record_querying.html

    (事实上,我强烈建议您阅读所有 Rails 指南,以了解 Rails 的工作原理)。

    我还更新了作用域以在 lambda 周围添加大括号 - 这些天推荐用于 Rails 作用域。

    【讨论】:

    • @Taryn_East 感谢您的建议。我已经阅读了所有指南几次。我刚刚重新阅读了 Active Record Query Interface 指南 - 我在指南中找不到任何解释 where () 中第一个哈希的含义的内容。 '' 是什么意思?再次感谢您的帮助。
    • 我尝试了这个建议。我收到一个错误(我还没有弄清楚如何翻译成英文):语法错误,意外'(',期待keyword_do_LAMBDA或tLAMBEG ...third_party_cmets,-> where(“comment.user_id ?” ,波特... ...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-04
    • 1970-01-01
    相关资源
    最近更新 更多