2009-12-14 52 views
1

我有幾個模型(網站和服務器),通過has_many:through與eachother相關。他們也都屬於:用戶。在我的網站/新視圖中,我創建了一個新網站,並使用嵌套的form.fields_for:servers創建了一個新的服務器。一切都按預期工作,除了最終創建的服務器沒有填充user_id。我如何確保它是?Rails的外鍵在嵌套形式爲零

我sites_controller新創建的方法:

def new 
    @user = current_user 
    @site = @user.sites.build 
    @servers = @user.servers.all 

    # let there be one server linked 
    @site.site_servers.build 

    # @user.servers.build if @user.servers.empty? 
    @site.servers.build(:user_id => current_user.id) if @site.servers.empty? 

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

    def create 
    @site = current_user.sites.build(params[:site]) 

    respond_to do |format| 
     if @site.save 
     flash[:notice] = 'Site was successfully created.' 
     format.html { redirect_to(@site) } 
     format.xml { render :xml => @site, :status => :created, :location => @site } 
     else 
     format.html { render :action => "new" } 
     format.xml { render :xml => @site.errors, :status => :unprocessable_entity } 
     end 
    end 
    end 

如果您發現該註釋行,這些事情我試過,沒有工作。

型號:

class User < ActiveRecord::Base 
    acts_as_authentic 

    has_many :sites 
    has_many :servers 
end 

class Site < ActiveRecord::Base 

    belongs_to :user 

    has_many :site_servers 
    has_many :servers, :through => :site_servers 

    accepts_nested_attributes_for :site_servers, :allow_destroy => true 
    accepts_nested_attributes_for :servers, :allow_destroy => true 

    validates_presence_of :name, :on => :create, :message => "Name is required" 
end 

class Server < ActiveRecord::Base 
    attr_encrypted :password, :key => '393b79433f616f445f652a752d', :attribute => 'crypted_password' 

    belongs_to :user 

    has_many :site_servers 
    has_many :sites, :through => :site_servers 

    validates_presence_of :url, :on => :create, :message => "URL is required." 
    validates_presence_of :username, :on => :create, :message => "Username is required." 
    validates_presence_of :password, :on => :create, :message => "Password is required." 


    def name 
    username + "@" + url 
    end 

    def to_s 
    name 
    end 

end 

class SiteServer < ActiveRecord::Base 
    belongs_to :site 
    belongs_to :server 

    has_one :user, :through => :site 
end 

而且這裏是我的架構:

ActiveRecord::Schema.define(:version => 20091203045550) do 

    create_table "servers", :force => true do |t| 
    t.string "url" 
    t.string "username" 
    t.string "crypted_password" 
    t.integer "port" 
    t.integer "user_id" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "site_servers", :force => true do |t| 
    t.integer "site_id" 
    t.integer "server_id" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "sites", :force => true do |t| 
    t.string "name" 
    t.string "url" 
    t.string "path" 
    t.integer "user_id" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "users", :force => true do |t| 
    t.string "username" 
    t.string "email" 
    t.string "crypted_password" 
    t.string "password_salt" 
    t.string "persistence_token" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

end 
+0

粘貼您的模型。 – bensie 2009-12-14 02:47:15

回答

2

你有一個隱藏字段在服務器形式USER_ID?

<%= f.hidden_field :user_id %> 

如果不是,則即使您設法正確設置值,該值也不會傳回。如果您向表單添加隱藏字段,那麼您已註釋掉的行將會起作用。

@site.servers.build(:user_id => current_user.id) if @site.servers.empty? 

其實我喜歡,設置用戶ID的創建方法更好,因爲否則你介紹的人起草了自己的表單提交,創造下其他人的用戶ID事情的可能性的想法。我不知道安全在你的應用中是否是一件大事,但我永遠不會相信從窗體發送的用戶ID。

+0

啊。沒有意識到我需要這樣做來堅持id。說得通。我會手動填充,因爲你提出了安全問題。謝謝。 – devth 2009-12-14 04:01:28

+0

呃是啊,那裏有一個巨大的安全問題 - 從來沒有這樣做。 – bensie 2009-12-14 04:03:41

1

我猜問題是在你的create行動。新的行動只是建立Ruby對象 - 你需要確保有在創建操作類似構建代碼:

def create 
    @site = current_user.sites.build(params[:site]) 
    @site.save 
end 
+0

感謝您的回覆。我剛剛也粘貼了我的創建方法。我已經在使用您發佈的確切代碼。我認爲原因是因爲服務器是作爲網站的孩子而創建的。網站只是認爲它需要維護站點和服務器之間的關係。網站如何知道它也需要告訴服務器正確的user_id? – devth 2009-12-14 03:40:27

+0

是否需要手動完成?似乎有點hackish,但也許我可以這樣做: @ site.servers.first.user_id = current_user.id 在我的創建方法。 – devth 2009-12-14 03:45:25

+0

我明白你現在在說什麼,但我很難試圖找出你想要完成的事情。你爲什麼使用has_many:servers,:through =>:site_servers?我不理解連接表的目的。我看到它的方式,用戶應has_many:網站,網站應has_many:服務器,和用戶應has_many:服務器,通過=>:網站。 – bensie 2009-12-14 03:47:52