2012-10-03 20 views
0

我在嘗試將新條目保存到數據庫時遇到問題。在提交時,項目應保存到項目表中,該項目中的技術/技術應保存到名爲Technols的技術表中,這些技術表之間的關係存儲在名爲Projecttechnols的表中。Ruby on Rails:項目控制器中的RuntimeError

繼承人我的新動作:

def new 
    @project = Project.new 
    @technol = Technol.new(params[:tech]) 

@all_technols = Technol.all 
tech_ids = params[:technols][:id].reject(&:blank?) unless params[:technols].nil? 


@project_technol = @project.projecttechnols.build 





#@project_technol = Projecttechnol.new 

    respond_to do |format| 
     format.html # new.html.erb 
     format.json { render json: @project } 
    end 
    end 

創建行動:

def create 
    @all_technols = Technol.all 
    @project = Project.new(params[:project]) 

@technol = Technol.new(params[:tech]) 




params[:technol].each_value do |tech| 

technology = Technol.find_by_tech(tech.strip) 

@project_technol = @project.projecttechnols.build(:technol_id => technology.id) 

end 


    @project.client = params[:new_client] unless params[:new_client].blank? 
    @project.project_owner = params[:new_project_owner] unless params[:new_project_owner].blank? 
    @project.tech = params[:new_tech] unless params[:new_tech].blank? 
    @project.role = params[:new_role] unless params[:new_role].blank? 
    @project.industry = params[:new_industry] unless params[:new_industry].blank? 
    @project.business_div = params[:new_business_div] unless params[:new_business_div].blank? 

    respond_to do |format| 
     if @project.save 
     format.html { redirect_to @project, notice: 'Project was successfully created.' } 
     format.json { render json: @project, status: :created, location: @project } 
     else 
     format.html { render action: "new" } 
     format.json { render json: @project.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

而我的3種型號:

Project.rb

class Project < ActiveRecord::Base 
    attr_accessible :edited_first_name, :edited_last_name, :first_name, :last_name, :business_div, :client, :customer_benifits, :edited_date, :end_date, :entry_date, :financials, :industry, :keywords, :lessons_learned, :project_name, :project_owner, :role, :start_date, :status, :summary, :tech , :technols 

validates_presence_of :business_div, :client, :customer_benifits, :end_date, :financials, :industry, :keywords, :lessons_learned, :project_name, :project_owner, :role, :start_date, :status, :summary 




has_many :projecttechnols 
has_many :technols, :through => :projecttechnols 


def self.like(text); "%#{text}%"; end 

    def self.search(search_client, search_industry, search_role, search_techs_ids, search_business_div, search_project_owner, search_status, search_start_date_dd, search_start_date_A, search_start_date_B, search_keywords) 
    # start with a scoped query, to apply more scopes on it afterwards 
    _projects = Project.scoped 
    # then, for each of the parameters, apply the scope only if present 
    if search_client.present? 
     _projects = _projects.where ['client LIKE ?', like(search_client)] 
    end 
    if search_industry.present? 
     _projects = _projects.where ['industry LIKE ?', like(search_industry)] 
    end 
    if search_role.present? 
     _projects = _projects.where ['role LIKE ?', like(search_role)] 
    end 

#_projects = _projects.joins(:technols). 
#    where("technols.id" => search_techs_ids) 



#_projects = _projects.joins(:projecttechnols).where("projecttechnols.id" => search_techs_ids) 


if search_techs_ids.present? 
_projects = _projects.joins(:technols).where("technols.id" => search_techs_ids) 
end 



    if search_business_div.present? 
     _projects = _projects.where ['business_div LIKE ?', like(search_business_div)] 
    end 
    if search_project_owner.present? 
     _projects = _projects.where ['project_owner LIKE ?', like(search_project_owner)] 
    end 

    if search_status.present? 
     _projects = _projects.where ['status LIKE ?', like(search_status)] 
    end 



todays_date = DateTime.now.to_date 

if !search_start_date_A.blank? or !search_start_date_B.blank? 
    search_start_date_A = Date.parse(search_start_date_A).strftime("%Y-%m-%d") 
    search_start_date_B = Date.parse(search_start_date_B).strftime("%Y-%m-%d") 
    todays_date = nil 
    search_start_date_dd = nil 

    end 

if search_start_date_dd.blank? 
    todays_date = nil 
end 


if search_start_date_A.present? or search_start_date_B.present? 

     _projects = _projects.where [' DATE(start_date) BETWEEN ? AND ?', search_start_date_A, search_start_date_B] 
    end 


       if search_start_date_dd.present? 
     _projects = _projects.where ['DATE(start_date) BETWEEN ? AND ?', search_start_date_dd, todays_date] 
    end 




    if search_keywords.present? 
     _projects = _projects.where ['keywords LIKE ?', like(search_keywords)] 
    end 
    # now you have applied only the present scopes. return the result, and watch 
    # the query as it executes. 
    _projects 
    end 


def self.paginated_for_index(projects_per_page, current_page) 
    paginate(:per_page => projects_per_page, :page => current_page) 
    end 

end 

technol.rb

class Technol < ActiveRecord::Base 
    attr_accessible :tech 

has_many :projecttechnols 
has_many :projects, :through => :projecttechnols 
end 

projecttechnol.rb

class Projecttechnol < ActiveRecord::Base 
    attr_accessible :project_id, :technol_id 

belongs_to :technol 
belongs_to :project 
end 

,這裏是新的觀點,我認爲這是導致該問題的一部分:

<div class="tech"> 

<% common_techs = [['Mainframe'],['UNIX'],['Windows Servers'],['Networking'],['CISCO'], ['Win7'], ['Telephony'], ['Web services'], ['Website'], ['Cloud'], ['Virtualisation'], ['Data Centre']] %> 
<% db_techs = Technol.all.map {|p| [p.tech]}.uniq %> 

<% all_tech = common_techs + db_techs %> 


<%= form_for(@technol) do |tech| %> 
<div class="field"> 
    <%= tech.label :tech %><br /> 
    <%= tech.text_field :tech %> 
    </div> 
<%end%> 

當我點擊提交按鈕來創建一個新的項目,我得到這個錯誤:

RuntimeError in ProjectsController#create 

Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id 

app/controllers/projects_controller.rb:116:in `block in create' 
app/controllers/projects_controller.rb:112:in `each_value' 
app/controllers/projects_controller.rb:112:in `create' 

這些都是我的PARAMS:

{"utf8"=>"✓", 
"authenticity_token"=>"sPyJbgBKTxa9iHWF9r0Gg/0R/v0l0/e8KwXpPebzdus=", 
"project"=>{"project_name"=>"", 
"status"=>"Active", 
"client"=>"", 
"business_div"=>"", 
"project_owner"=>"", 
"start_date"=>"01-10-2012", 
"entry_date"=>"2012-10-03", 
"end_date"=>"09-10-2012", 
"role"=>"", 
"industry"=>"", 
"summary"=>"", 
"lessons_learned"=>"", 
"customer_benifits"=>"", 
"financials"=>"", 
"keywords"=>""}, 
"new_client"=>"", 
"new_business_div"=>"", 
"new_project_owner"=>"", 
"technol"=>{"tech"=>"TESTER"}, 
"new_role"=>"", 
"new_industry"=>"", 
"commit"=>"Save New Project"} 

我新的軌道,從而努力時,請記住這一點幫我。所有的幫助將不勝感激。提前致謝。

UPDATE:

工作代碼

def create 
    @all_technols = Technol.all 
    @project = Project.new(params[:project]) 

@technol = Technol.new(params[:tech]) 




params[:technol].each_value do |tech| 

technology = Technol.find_or_create_by_tech(tech.strip) 

@project_technol = @project.projecttechnols.build(:technol_id => technology.id) 

end 

回答

2

這是一個有點難以通過一切篩選,但是當你看到這條消息:

Called id for nil, which would mistakenly be ... 

這意味着你試圖調用一個方法( .id在這種情況下)對未加載正確的對象。如果我猜的話,這將是在這裏你創建行動:

technology = Technol.find_by_tech(tech.strip) 
    @project_technol = @project.projecttechnols.build(:technol_id => technology.id) 
end 

具體technology.id。你確定這一行:

technology = Technol.find_by_tech(tech.strip) 

返回預期結果?如果您用Technol.first替換它,是否會停止該錯誤?如果是這樣,find_by_tech失敗。

+0

更改爲'Technol.first'使項目保存。但它將技術表中的第一項技術保存到該項目中。我希望'TESTER'成爲新技術的地方。即使'TESTER'已經不在表格中了。這只是我在創建一個新項目時在我的新視圖中鍵入的技術 – Jazz

+1

這只是爲了確認診斷;)您的評論解釋了問題。您正在嘗試添加新技術,但當然'find_by_tech'不會找到它,結果'technology.id'失敗。如果您想添加創建新Technol的可能性,請將包含'find_by_tech'的行更改爲:'technology = Technol.find_or_create_by_tech(tech.strip)',您應該可以在實時添加新技術! –

+0

謝謝,謝謝,謝謝! – Jazz