2014-10-10 16 views
0

我發佈了一個關於如何在同一控制器中的操作之間共享變量的問題。我發現這個問答最主要的回答了我的問題,但仍然留下了這個提交中提出的未決問題。 這裏是鏈接的Q/AI發現可能會幫助別人:Same instance variable for all actions of a controllerRails4如何在before_filter中定義變量值或在其他UI過程方法中定義私有操作時定義變量值?

這裏是鏈接,我,我跟上面的鏈接回答最初的問題:In Rails4 How to assign variables in one controller action and use the value of it in another controller action

現在,我知道我可以使用before_filter並創建一個私有操作,然後可以從控制器中的各種操作中引用該操作,這對於已知的常量變量來說顯得非常重要,我如何在基於用戶操作改變值並根據用戶操作定義的特定情況下對其進行設置 在用戶交互操作中?

我有一個名爲'evaluate_media'的方法。此方法允許用戶從各種目錄路徑中選擇一個文件,然後在選定的視頻文件上運行媒體信息,並解析xml中的某些屬性(如比特率,aspect_ratio)並將值分配給動作中的變量。有沒有什麼辦法可以將這個動作中的查找變量和賦值變量與common_components這樣的其他動作共享,而不需要它是私有的,只是用於變量賦值?你能告訴我一個如何做到這一點的例子嗎?我確實嘗試了before_filter,它甚至沒有調用插入。它只是刷新頁面。在我收集這些信息到我的evaluate_media動作之後,我有一個保存按鈕,調用save_file方法來存儲這個信息在evaluate_media操作中收集的信息。

這裏有2種定義的方法:

def save_file  

     src_location = @radio_button_value 
     directory = "#{@dir_path_choice}" 
     full_path = @filepathname 
     full_filename = "#{@filepath}" 
     alias_code = "#{@file_alias}" 
     validate_status = "#{@file_status}" 
     error_msg = "#{@file_msg}" 
     video_alias_match = "#{@msg_dtl1}" 
     audio_alias_match = "#{@msg_dtl2}" 
     video_format = "#{@video_format}" 
     video_bitrate = "#{@video_bitrate}" 
     video_width = "#{@video_width}" 
     video_height = "#{@video_height}" 
     video_framerate = "#{@video_framerate}" 
     video_aspect_ratio = "#{@video_aspectratio}" 
     video_scan_type = "#{@video_scantype}" 
     video_scan_order = "#{@video_scanorder}" 

     @file_alias_tfile = FileAliasTfile.new(:src_location => src_location, :directory => directory, :full_path => full_path, :full_filename => full_filename, :file_ext => '', 
                 :assigned_status => 'Unassigned', :file_status => 'Saved', :alias_code => alias_code, :validate_status => validate_status, :error_msg => error_msg, 
                 :video_alias_match => video_alias_match, :audio_alias_match => audio_alias_match, :video_format => video_format, :video_bitrate => video_bitrate, 
                 :video_width => video_width, :video_height => video_height, :video_framerate => video_framerate, :video_aspect_ratio => video_aspect_ratio, 
                 :video_scan_type => video_scan_type, :video_scan_order => video_scan_order, :video_alias_code => '', :audio_alias_code => '', 
                 :bus_prod_initiative_id => 0, :status => 'Active', :start_date => DateTime.now.to_date, :end_date => '', :deleted_b => 0, 
                 :created_by => 'admin', :updated_by => 'admin') 


    if @file_alias_tfile.save 
     redirect_to mainpages_home_path, :notice => "The file alias validation has been saved." 
    else 
     redirect_to alias_mainpages_home_path, :notice => "The file alias validation has not been saved." 
    end 
    end 

def evaluate_media 

    @state = 'post' 
    @radio_button_value = params[:location] 

    @stored_file = FileAliasTfile.where(:full_path => params[:filepath2], :deleted_b => 0).first 

    if @stored_file.present? 
     @file_exists_flag = 'Y' 
     @file_exists_msg = 'This File and Alias has been saved in application.' 
    else 
     @file_exists_flag = 'N' 
     @file_exists_msg = 'This File and Alias has NOT been saved in application yet.' 
     end 

      root_dir = '/watchfolder/miniprod/hot/' 
      provider_dir = "" 

     @selected_filepath = params[:filepath2] 
     @filepath = params[:filepath2] 

     @media_xml = ::MediaInfo.call(@filepath) 
     @alias_xml = ::AliasGenerator.call(@media_xml) 

     @media_xml_for = "" 
     @alias_xml_for = "" 
     REXML::Document.new(@media_xml).write(@media_xml_for, 1) 
     REXML::Document.new(@alias_xml).write(@alias_xml_for, 1) 
     alias_parse_doc = "" 
     media_parse_doc = "" 
     alias_parse_doc = REXML::Document.new(@alias_xml) 
     media_parse_doc = REXML::Document.new(@media_xml) 


     #parse Alias XML Doc 
     @aliasgen_ver = REXML::XPath.each(alias_parse_doc, "/aliasGenerator vr=/text()") { |element| element }  
     @file_alias = REXML::XPath.each(alias_parse_doc, "*//alias/text()") { |element| element } 
     @file_status = REXML::XPath.each(alias_parse_doc, "*//error/text()") { |element| element } 
     @file_msg = REXML::XPath.each(alias_parse_doc, "*//error_m/text()") { |element| element } 
     @msg_dtl1 = REXML::XPath.each(alias_parse_doc, "*//closestvideoalias/text()") { |element| element } 
     @msg_dtl2 = REXML::XPath.each(alias_parse_doc, "*//closestaudioalias/text()") { |element| element } 

     #parse Video Media Info XML Doc 
     @filepathname = REXML::XPath.each(media_parse_doc, "*//Complete_name/text()") { |element| element } 
     @video_format = REXML::XPath.each(media_parse_doc, "//track[@type='Video']/Format/text()") { |element| element } 
     @video_bitrate = REXML::XPath.each(media_parse_doc, "//track[@type='Video']/Bit_rate/text()") { |element| element } 
     @video_width = REXML::XPath.each(media_parse_doc, "//track[@type='Video']/Width/text()") { |element| element } 
     @video_height = REXML::XPath.each(media_parse_doc, "//track[@type='Video']/Height/text()") { |element| element } 
     @video_aspectratio = REXML::XPath.each(media_parse_doc, "//track[@type='Video']/Display_aspect_ratio/text()") { |element| element } 
     @video_framerate = REXML::XPath.each(media_parse_doc, "//track[@type='Video']/Frame_rate/text()") { |element| element } 
     @video_scantype = REXML::XPath.each(media_parse_doc, "//track[@type='Video']/Scan_type/text()") { |element| element } 
     @video_scanorder = REXML::XPath.each(media_parse_doc, "//track[@type='Video']/Scan_order/text()") { |element| element } 

     render :action => :index 
    end 

回答

0

我怎麼把它架在我的具體情況下的值更改基於用戶行爲 ,並在被定義用戶交互式操作?

如果您在多個操作中執行相同的計算,並且唯一發生更改的是計算中使用的某個值,則無需在兩個或多個操作中編寫基本相同的代碼,您可以創建該做的計算方法:

def do_calculation(val1, val2) 
    #Use val1 and val2 to perform some calculation 
    result 
end 

如果你把這種方法在你的控制器,那麼該方法可以在任何動作中調用。您將該方法設爲私有的原因是爲了使路由無法使用該方法。因爲沒有路線可以擊中該方法,所以該方法不稱爲動作 - 它只是稱爲輔助方法。這裏是什麼樣子:

class YourController < ApplicationController 

    def index 
    @files = do_calculations(params[:a], params[:b]) 
    end 

    def show 
    @files = do_calculation(params[:b], params[:c]) 
    end 

    private 
    def do_calculation(val1, val2) 
     #Use val1 and val2 to perform some calculation... 
     result 
    end 

end 

軌道4具有做同樣的事情更復雜的方式 - 它涉及到把在另一個文件中的helper方法。在您的應用程序/控制器/目錄中,有一個名爲concerns /的目錄,您可以這樣做:

app/controllers/concerns/file_methods。RB:

module FileMethods 
    extend ActiveSupport::Concern 

    def do_calculation(x, y) 
    x*y 
    end 
end 

然後在你的控制器,你這樣做:

class YourController < ApplicationController 
    include FileMethods 

    #Then you can call do_calculation() in any of the actions 

end 

如果你這樣做的,其他控制器可以包括FileMethods模塊,也因此這種方式更加靈活。另外,FileMethods模塊內部還有其他一些功能,因爲它擴展了ActiveSupport :: Concern。

有沒有什麼辦法可以與 這個動作共享查找並分配變量與其他動作...沒有它是私人的?

如果你是說,你的計算需要用戶輸入,並因此before_filter(Rails3)/before_action(Rails4)將無法​​正常工作,而你只想要做的計算一次,然後這裏的交易。網絡是無狀態,這意味着每個請求開始就好像它是通過互聯網發送的第一個請求。 無狀態表示沒有狀態,即變量,與隨後的請求共享。換句話說,一旦服務器完成處理請求,它將刪除與該請求相關的所有內容。所以,當你的瀏覽器詢問「服務器先生,你能請求檢索先前請求中的值並在這個請求中使用它嗎?」時,服務器回答:「對不起,我不知道你在說什麼。有一個嚴重的失憶症病例,爲此我表示歉意,但據我記憶,你以前從未向我提出過​​請求,讓我查看我的記錄......不,這裏沒有。找回,再見,隨時來。「

無狀態在rails中的工作方式是,對於每個請求,rails都會創建控制器的一個實例,例如, inst = YourController.new,然後rails調用inst.actionA,它創建actionA中指定的@variables,並將@variables自己創建爲inst。然後使用inst執行視圖,這使得inst的@variables在視圖中可用。並且對於後續請求,軌道確實是inst = YourController.new,然後是inst.actionB。因此,您的控制器的第一個實例將與自己附加到實例的@variables一起被擦除。

然而,互聯網的無狀態性質已被證明是不方便的網絡程序員,所以發明了各種方案,使變量持續請求。你有沒有聽說過餅乾? Cookies用於在用戶的計算機上存儲小塊數據,然後隨後的請求將該數據返回給服務器,因此它的值爲,就好像該值在請求之間的服務器上保留。有一個更精緻的方案會話,它允許你做同樣的事情。使用rails中的會話,rails會自動爲您設置用戶計算機上的cookie。你所要做的就是處理一個名爲session的對象,該對象會自動爲你創建,就像它是一個哈希。如果在一個動作中(即對於一個請求)在session對象上設置鍵/值對,則可以在另一個動作中(即針對另一個請求)在會話對象中查找它。

下面是一個例子:

class YourController < ApplicationController 

    def action1 
    val1 = params[:val1] 
    val2 = params[:val2] 

    #Use the user input to produce some data: 
    dir_list = .........val1......val2..... 

    session[:dir_list] = dir_list 
    end 

    def action2 
    @dir_list = session[:dir_list] 
    end 

end 

但是......根據你最近的一連串的問題,你可能想看看答案您以前的問題 - 從你的Ajax問題。你可能會發現這個問題的答案解決了你現在試圖解決的很多問題。