如何正确使用belongs_to和has_many?

时间:2011-01-08 03:30:27

标签: ruby-on-rails sqlite

我整天都在调试这个。 我的应用程序中有两个型号:teaClass&茶。在teaclass.rb中,我有

has_many :teas

在tea.rb中,我有'belongs_to:teaclass`。

我尝试将网址设为"..teaclasses/:id/teas/:id";,因此在teas_controller.rb中,我放了before_filter :get_teaClass

def show
@tea = @teaclass.teas.find(params[:id])

respond_to do |format|
  format.html # show.html.erb
  format.xml  { render :xml => @tea }
end
end

def new
if @teaclass.teas
    @tea = @teaclass.teas.new
    @teaclass.teas << @tea 
    #@tea = Tea.new
    else
        flash[:notice=>"failed"]
        @tea = Tea.new 
        @teaclass.teas << @tea 
    end
respond_to do |format|
  format.html # new.html.erb
  format.xml  { render :xml => @tea }
end
end

def get_teaClass
    begin
        @teaclass = Teaclass.find(params[:teaclass_id])rescue
        redirect_to teaclass_path, :notice => "Teaclass Required!"
    end
 end

但我一直收到错误提示“未知属性:teaclass_id”

/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2906:inassign_attributes'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2902:in `each'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2902:in `assign_attributes'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2474:in `initialize'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/associations/association_collection.rb:380:in `new'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/associations/association_collection.rb:380:in `send'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/associations/association_collection.rb:380:in `method_missing'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2178:in `with_scope'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/associations/association_proxy.rb:207:in `send'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/associations/association_proxy.rb:207:in `with_scope'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/associations/association_collection.rb:376:in `method_missing'
/home/jianpchen/repo/Teashop/app/controllers/teas_controller.rb:31:in `new'

任何人都可以帮我这个吗?谢谢。

2 个答案:

答案 0 :(得分:3)

  

我尝试让网址看起来像这样“..teaclasses /:id / teas /:id”;所以在teas_controller.rb中,我把before_filter:get_teaClass

这只有在您尝试设置嵌套路由时才重要,但ID听起来并不像您这样做。

您需要做的是将外部ID添加到数据库中。因此,请检查schema.rb并确保该列存在。

以下是您需要做的事情。

  1. 确保您在数据库表tea中实际拥有外来字。
  2. 如果您跳到下一步,我将向您展示更好的编写代码的方法。
  3. 如果您的'茶'桌上没有'tea_class_id'作为整数值,则需要添加它。
  4. 脚本/生成迁移add_tea_class_id_to_tea
  5. rake db:migrate
  6. 现在这就是你的代码编写方式
  7. 的routes.rb

    map.resources :teas
    map.resources :teas_classes
    

    模型

    模型/ tea.rb

    class Tea < ActiveRecord::Base
        belongs_to :tea_class
    end 
    

    tea_class.rb

    class TeaClass < ActiveRecord::Base
        has_many :teas
    end 
    

    控制器

    teas_controller.rb

    def new
       @tea = Tea.new
    end
    
    def show
      @tea = tea.find(params[:id)
    end
    
    def create
        @tea = Tea.new(params[:tea])
        if @tea.save
            redirect_to teas_path
        else
            render :action => 'new'
        end
    end 
    

    的观点

    这非常重要。确保在创建茶时将:tea_class_id作为参数传递,否则它不知道如何进行关联。它有点落后于舞台,因为您发送params[:tea],但它位于实际发送tea_class_id的参数中。

    所以......在你的视图中,你需要有某种方式让用户选择一个类别,或者你有茶类,这通常是在一对多关联时用选择框完成的。< / p>

    new.html.erb

    <% form_for(@tea) do |t| %>
        <%= t.collection_select :tea_class_id TeaClass.all, :id, :name %>
    <% end %>
    

    确保您有茶类实际填充collection_select方法。谷歌加上rails api,如果你不知道发生了什么。

    嵌套路由(侧面)

    看起来你正试图获得像teaclasses/:id/teas/:id这样的路线。这称为嵌套路由,您需要在routes.rb中设置它。

    map.resources :tea_classes_ do |tea_classes|
       tea_classes :teas
    end
    map.resources :teas
    

    然后您可以链接到teas_classes/pour/teas/chinese。您应该知道此命令rake routes。它将帮助您了解路径的工作原理。

    但是如果你只想让链接开始,它应该是这样的:

    <%= link_to "Teas", tea_classes_teas_path(@tea_class)%>
    

    您需要提供@teas链接,因为它从中获取了ID,当您单击它时会将其提供给teas_controller' as参数[:teas_class_id]`。没有,你不需要做任何事情。它会自动出现在网址中。

答案 1 :(得分:0)

如果查看日志,您将看到params包含的内容。鉴于您的代码和解释,params中没有键teaclass_id。你很可能正在寻找:id。如果你想访问:teaclass_id,你可能需要在你的路线中设置

match 'controller/:teaclass_id' => 'controller#show'