has_many_through关联不在params中插入值来连接表而是插入null

时间:2014-11-21 14:57:05

标签: ruby-on-rails-3

修改

我是铁杆新手并且在这一步陷入困境。在互联网上尽我所能但无法解决这个问题。请帮忙!我正在使用Rails 3.2.13。

这就是我的模特现在的样子。请原谅我的拼写错误,如果有的话,因为这是一个例子。清理了一下,但同样的问题。可能是错误不确定。

我有3个型号:

1.Cuisine (example Thai/Mexican/Italian) 

 class Cuisine < ActiveRecord::Base
 has_many :testers, :through => :ratings
 has_many :ratings, :inverse_of => :cuisine

 2.Testers

 class Tester < ActiveRecord::Base
 has_many :cuisines, :through => :ratings
 has_many :ratings, :inverse_of => :tester

 3.Rating (note:had the inverse_of here too but did not work)

 class Rating < ActiveRecord::Base
 belongs_to :tester
 belongs_to :cuisine

 testers_controller

class TestersController < ApplicationController

 def update  ##TO DO: SAVE (tester + cuisine IDS) IN THE ratings/JOIN TABLE 
 @tester = Tester.find(params[:id]) 
 @tester.ratings.create
 render text: 'Success'
 end

这是视图中的表单。我没有使用/渲染任何部分练习。

 <%= form_for :rating, url: ratings_path do |f| %>

   <h3>Review:</h3>
     <% for cuisine in Cuisine.find(:all) %>
    <div>
      <%= check_box_tag("tester[cuisine_ids][]", cuisine.id) %>
      <%= cuisine.cuisine_name %>
    <% end %>
  </div>
    <p><%= f.submit %></p>
  <% end %>

开发日志显示如下。

         Started PUT "/testers/3" for 127.0.0.1 at 2014-11-27 16:53:31 -0700
 Processing by TestersController#update as HTML
 Parameters: {"utf8"=>"✓",         "authenticity_token"=>"5awCMjqwUSHaByj1XFDs5UKZUjyvMoigB88NZCFWgSE=", "tester"=>  {"cuisine_ids"=>["3", "6"]}, "commit"=>"Update Tester", "id"=>"3"}
   User Load (0.3ms)  SELECT `testers`.* FROM `testers` WHERE `testers`.`id` = 3 LIMIT 1
    Cuisine Load (0.4ms)  SELECT `cuisines`.* FROM `cuisines` WHERE `cuisines`.`id` = 3 LIMIT     1
     (0.1ms)  BEGIN
   SQL (0.2ms)  INSERT INTO `ratings` (`created_at`, `created_by`, `cuisine_id`,       `updated_at`, `tester`, `tester_id`) VALUES ('2014-11-27 23:53:31', NULL, NULL, '2014-11-27       23:53:31', NULL, 3)
   (0.4ms)  COMMIT
  Rendered text template (0.0ms)
 Completed 200 OK in 15ms (Views: 0.3ms | ActiveRecord: 3.8ms)

这里有几个问题。 1. Cuisine_ids未插入评级表中 2.如果我已将join_id = 1和cuisine_ids = [2,3]的组合已经存在于连接表中,那么它什么都不做。我想再次插入相同的值。这是我想允许插入语句用于插入重复的条目。这就是我的评级如何运作。 3.如果我有tester_id =和cuisine_ids = [1,2,3]的组合,如果我选择cuisine_ids = [2,3],那么它会以某种方式删除cuisine_ids [1,2,3]并再次插入[] 2,3]。所以首先它执行 1.DELETE来自rating_id = 1的评级(然后再次运行插入)

我想要做的就是使用连接表中的复选框保存用户选择的记录。我想在该连接表中允许重复(对于tester_id和cuisine_ids组合)。该连接表可能类似于交易表,即一个产品可能具有同一客户的重复/重复订单。但是,整行仍然是唯一的,因为rails在每个表上都有自己的主键。

如果您需要更多信息,请与我们联系。有人请帮忙!!!!

由于

1 个答案:

答案 0 :(得分:0)

我需要更多地了解您的数据模型,但我可以在此提供一些一般性指导。

class Cuisine < ActiveRecord::Base
 attr_accessible :cuisine_name, :id, :cuisine_id
 attr_accessor  :tester, :cuisine_ids
 has_many :testers, :through => :ratings
 has_many :ratings

首先,将“:id”添加到attr_accessible没有意义。你不需要它,因为它会让人们能够更新记录的id。我不确定“cuisine_id”是什么,它在cuisines表中是没有意义的。

你绝对不需要attr_accessor。你应该添加反向关系。

所以这就是我们离开的地方:

class Cuisine < ActiveRecord::Base
  attr_accessible :cuisine_name
  has_many :ratings, :inverse_of => :cuisine
  has_many :testers, :through => :ratings

接下来是Tester:

class Tester < ActiveRecord::Base
 attr_accessible :tester_name, :id, :tester_id
 attr_accessor  :cusines
 has_many :cusines, :through => :ratings
 has_many :ratings

同样,您的attr_accessible令人困惑。你也有错误的“美食”。最后,你不需要attr_accessor,而且它实际上会“隐藏”真正的“美食”关系。以下是我们最终的结果:

class Tester < ActiveRecord::Base
 attr_accessible :tester_name
 has_many :ratings, :inverse_of => :tester
 has_many :cuisines, :through => :ratings

最后,收视率。这很简单,实际上看起来不错,但令我印象深刻的是,attr_accessors可能至少存在某种“评级”属性。由于我不知道那里有什么,我们只需添加反向关系:

class Rating < ActiveRecord::Base
 belongs_to :tester, :inverse_of => :ratings
 belongs_to :cuisine, :inverse_of => :ratings

如果有正确的话,可以使其余部分得到修复。

看着你的评级控制器,这有点令人困惑。我不知道“评级”行动应该做什么。你正在混合复数和单数以及所有这些。你有另一种方式拼错的“美食”。让我们从视图开始:

 <h3>Review:</h3>
 <% for cuisine in Cuisine.find(:all) %>
   <div>
     <%= check_box_tag("tester[cuisine_ids][]", cuisine.id) %>
     <%= cuisine.cuisine_name %>
   </div>
 <% end %>
 <p><%= f.submit %></p>
 <% end %>

据推测,你没有包含“form_for”。我已经完成了至少需要的最小化,以至少正确渲染。它仍然不是你想要的,因为它不允许更新。

回到控制器,什么是“评级”应该做什么?这是你的“新”动作吗?

class RatingsController < ApplicationController

 def ratings
   @ratings=Rating.new
 end
 def create
   @tester= Tester.new(params[:tester])
   params[:tester][:cuisine_ids].each do |tester|
     @cus=@tester.ratings.build(:tester_id => tester)
     @cus.save
   end
 end

这是一般的清理工作。在创建之后,您仍然没有保存“@tester”或执行任何其他操作。如果你从testers的一般资源支架开始,你可以很容易地做到这一点。但是修复了这些问题后,你至少可以开始取得一些进展。

正如我在上面的评论中所说,你最好把它放在一边,阅读一个教程,然后重新审视。