【问题标题】:Ruby on Rails 5.1.4 couldn't find Model idRuby on Rails 5.1.4 找不到模型 ID
【发布时间】:2017-12-01 23:45:59
【问题描述】:

好的,我是 Rails 的新手,一般来说我没有太多的编码经验,所以这可能看起来很愚蠢,但这是我的问题:

我编辑了代码,所以这里是我当前状态的更新,包括更多信息:

投票和期权模型:

class Voting < ApplicationRecord
  has_many :options
  validates :vote, presence: true
  accepts_nested_attributes_for :options
end

class Option < ApplicationRecord
  belongs_to :voting
end

routes.rb:

Rails.application.routes.draw do
  resources :votings do
    resources :options
  end
  root 'votings#new'
end

投票/new.html.erb:

<h1>create new poll</h1>

<%= form_with scope: :voting, url: votings_path, local: true do |form| %>
    <p>
      <%= form.label :voting %><br>
      <%= form.text_area :content %>
    </p>
    <p>
      <%= form.fields_for :option do |option| %>
          <%= option.label 'Optionen' %><br>
          <%= option.text_field :vote %>
      <% end %>
    </p>
    <p>
      <%= form.submit %>
    </p>
<% end %>

投票/show.html.erb:

<p>
  <strong>Your Voting:</strong>
  <%= @voting.content %>
</p>
<ul>
  <p>
  <%= @options.vote %>
  </p>
</ul>

votings_controller.rb:

 class VotingsController < ApplicationController
      def show
        @voting = Voting.find(params[:id])
        @options = @voting.options
      end

      def new
        @voting = Voting.new
        @voting.options.build
  end

  def create
    @voting = Voting.new(voting_params)
    @voting.save
    redirect_to @voting
  end

  private
  def voting_params
    params.require(:voting).permit(:content, options_attributes: [:id, :vote])
  end
end

options_controller.rb:

class OptionsController < ApplicationController
  def create
    @voting = Voting.find(params[:id])
    @options = @voting.options.create(option_params)
    redirect_to voting_path(@voting)
  end

  private
  def option_params
    params.require(:option).permit(:vote)
  end
end

(我认为选项控制器中的一些代码与投票控制器相比是双倍的,我什至不确定是否需要)。

所以,我想在同一页面中创建一个带有相关选项的投票,然后在同一页面上显示投票及其选项(voting/new.html.erb 和voting/show.html.erb)。

这是我当前的错误信息:

VotingsController#create 中的 NoMethodError

#Voting:0x0000000be55208 的未定义方法“投票”

(从表单提交内容后显示。) 因此,到目前为止,new.html.erb 表单运行良好。

他似乎不知道该怎么做'投票'

<%= @options.vote %>

来自show.html.erb

我希望进一步的信息将有助于解决这个问题。

【问题讨论】:

  • “我没有正确选择”是什么意思?您看到什么错误/意外行为?日志显示什么?
  • 目前是“找不到 'id'=30 的选项”,看来他不喜欢表演动作,但我不确定这是否是问题
  • 您如何获得 option_id 30?可能 id 为 30 的选项已被删除
  • 你说“一切都很好,只是为了创造和展示”。现在你说“他似乎不喜欢表演动作”。所以我很困惑你说的是坏了。然而,这条线:@option = Option.find(params[:id]) 对我来说看起来很可疑,因为这是 VotingsController;我希望params[:id]Voting id,而不是Option id。
  • @TomLord 是的,它可以很好地创建和显示投票,但是由于我添加了选项部分(选项属于投票)它失败了。

标签: ruby-on-rails ruby


【解决方案1】:

您的问题在细节上有点稀缺,所以我只指出显而易见的问题,希望对您有所帮助。

您的投票控制器显示操作使用资源丰富的应用所期望的 voting 对象 ID 来查找 option 对象。

class VotingsController < ApplicationController
  def show
    @option = Option.find(params[:id]) # In a resource route this is a voting id!
    @voting = @option.user # what is option.user? Should be option.voting?
  end

这假设你的路由文件定义了resources :votings ?

【讨论】:

  • 首先谢谢你。好吧,那个“用户”的东西根本就不应该存在,我觉得我昨天太累了……我尝试了很多不同的东西,这似乎是一种耻辱,对不起!我编辑了它以避免进一步的混乱。是的,我的路由文件定义了resourses:votings
【解决方案2】:

我可以将您的问题解释为简单的答案,希望它可以帮助您排除疑问。

  def create
    @voting = Voting.new(voting_params)

    @voting.save
    redirect_to @voting
  end

在创建@voting 后的此操作中,它被重定向到show 操作,redirect_to @voting 这将创建一个链接链接此

/voting/:id

在显示操作中,我们发送投票的 id,因此很明显,在 show 操作中,当我们尝试获取 params[:id] 时,它将是投票的 id 而不是选项的 id 基本上应该是这里

  def show
    @voting = Voting.find(params[:id])
    @options = @voting.options
  end

希望它可以帮助您调试您的疑问,我不确定您是什么,让我知道以获得进一步的指导。谢谢

【讨论】:

    【解决方案3】:

    我假设您正在尝试展示带有选项的投票模型。

    所以 RESTful URL 是 /voting/&lt;voting_id&gt;。如果选项包含在 routes.rb 中作为投票的嵌套资源,要显示特定选项,则为 /voting/&lt;voting_id&gt;/options/&lt;option_id&gt;

    例如在localhost:3000/voting/1/options/20

    1是投票的id,20是选项的id

    所以你需要将显示方法更改为:

    def show
        @voting = Voting.find(params[:id])
        @options = @voting.options # Here it fetches all options for voting of the id passed 
    end
    

    我还建议将voting_params 方法修改为:

    def vote_params
        params.require(:voting).permit(:content, options_attributes: [:id, :vote])
    end
    

    由于一次投票有多个选项,因此您需要将每个选项的 id 列入白名单,否则它将被覆盖。你可以阅读更多关于here的内容。

    您拥有的模型关联与 rails guides 中的示例非常相似。阅读并重用代码作为开始。

    编辑:

    我建议现在使用 form_for(is soft-deprecated in rails 5) 而不是 form_with 来让事情正常工作。 您的 votes/new.html.erb 将如下所示:

    <h1>create new poll</h1>
    
    <%= <%= form_for @voting do |form| %> %>
        <p>
          <%= form.label :voting %><br>
          <%= form.text_area :content %>
        </p>
        <p>
          <%= form.fields_for :option do |option| %>
              <%= option.label 'Optionen' %><br>
              <%= option.text_field :vote %>
          <% end %>
        </p>
        <p>
          <%= form.submit %>
        </p>
    <% end %>
    

    像这样简单地使用 form_with 对我不起作用,因为 form_with 不支持自动生成 id。但请坚持重构,直到 rails 5.2 发布并且 form_for 可以替换为 form_with。这是来自this rails commit的推论

    【讨论】:

    • 感谢您的回答。你是对的,我想在同一个 new.html.erb 页面上创建带有选项的投票,然后在同一个 show.html.erb 页面上显示带有选项的投票......我认为你的答案是正确的方向,但它仍然不起作用。 (我也再次浏览了你的链接导轨)。我将编辑问题以将其更新为我的当前状态并添加更多详细信息。
    • 使用 form_for 而不是 form_with 让事情现在正常工作。但请注意 form_with 已被软弃用,即 form_for 将不会在以后的 rails 版本中得到支持。我已经使用有效的解决方案编辑了原始答案。
    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    • 2017-12-28
    • 2017-06-06
    相关资源
    最近更新 更多