【问题标题】:STI causing an issue when running application locallySTI 在本地运行应用程序时导致问题
【发布时间】:2015-02-18 15:45:56
【问题描述】:

我目前正在开发一个 Ruby on Rails v4 应用程序。

我为两个子用户buyerseller 创建了一个单表继承,继承自主user 表。由于这样做似乎在 localhost:3000 运行应用程序时出现问题。

以新用户身份注册时,我在浏览器页面上收到以下错误:

NoMethodError in Home#main
Showing /Users//Development/secret-project/app/views/layouts/home.html.erb where line #84 raised:
undefined method `seller' for User: 0x00000105714bb0

这是来自 home.html.erb 的代码:

        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">`

第 84 行 <%= render_navigation :context => (current_user.blank? ? :guest : :user) %> <%= render_navigation :expand_all => true, :context => :auth %> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid -->

浏览器还给出了以下详细信息:

app/views/layouts/home.html.erb:84:in '_app_views_layouts_home_html_erb___4408338611430956041_2173428480'
app/controllers/home_controller.rb:7:in `main'

home_controller 代码是:

class HomeController < ApplicationController

  def main
    @search = Search.new
    @jobs = Product.where("")

    render :layout => 'home'
  end

  def index
    page = params.has_key?(:page)? params[:page].to_i : 1
    per_page = 20
  end

  def contact
     redirect_to :contact
  end
end

我没有更新或完成什么?我唯一能解决的是第 84 行不正确。我认为它可能需要更改为:

<%= render_navigation :context => (current_user.blank? ? :guest : :user : :seller : :buyer) %>

创建新用户时,默认情况下它们不会存储为Seller,这让我感到困惑。

我的更改是否有意义,还是我完全处于错误的位置?

【问题讨论】:

  • 欢迎来到 Stack Overflow。需要记住的是,Stack Overflow 是一个参考网站,而不是社交网站。提出问题时,请尝试遵循格式中问题的平均外观,不要打扰表情符号。想想稍微亲切和温和的百科全书,或者类似于维基百科的东西,你会做得很好。
  • render_navigation 来自哪里?
  • @nicooga 在整个应用程序文件夹中搜索代码时,它只出现在我的两个视图文件中。这不是某种内置命令吗?
  • 我不这么认为。谷歌把我发到这里github.com/codeplant/simple-navigation。在您之前编写代码的人可能正在使用此 gem 来呈现导航。检查一下,它可能会引发一些关于什么是错误的见解。
  • @nicooga 你很准!在查看 Gemfile 之后,我发现 github.com/ShPakvel/simple_navigation_renderers 看起来像是最后一个编码器用来简化工作以拆分不同用户的视图和功能。你认为这会导致许多未来的问题吗?有没有更好的方法来完成这项工作?谢谢尼古加!

标签: ruby-on-rails ruby ruby-on-rails-3 activerecord


【解决方案1】:

我会在这里使用良好的多态性。

你的最后一行很奇怪,因为它从一个条件分支成 4 条路径。这甚至不仅仅是不可能的,它是一个语法错误。但是可以改写:

<%= render_navigation :context => (current_user.blank? ? :guest : current_user.role) %>

当然,它不会单独工作。你需要先定义role,从User开始

def role
  :user
end

在子类中,覆盖它:

def role
  :buyer # or :seller, in the other class
end

这是一个如何利用 STI 的架构示例。在这种确切的情况下,即使没有覆盖也可以很快解决:

def role
  class.name.underscore.to_sym
end

不过,它确实需要一些额外的计算。你已经被警告过了。你也可以把这个实现直接扔到视图中。 render_navigation 在我看来很像一个黑匣子,我不知道是否有更好的方法来处理这个问题。如果您提供有关它的更多详细信息,请告诉我,以便我可以相应地更新答案。

【讨论】:

  • 我将此添加到模型中的User 类中:def seller? self.user_type == 'seller' end def buyer? self.user_type == 'buyer' end 这有意义吗?它再次适用于 STI 类 BuyerSeller 但那是因为它使用的是旧方法。最后一位编码员只是将user_type 作为一列放在User 表中以区分两者。我被告知 STI 是处理子用户类 BuyerSeller 的正确方法?
  • @RubyMax STI 根据定义意味着子类共享其父表。那是是的。但请记住,您仍然可以从 Ruby 继承。
猜你喜欢
  • 2021-06-23
  • 2023-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多