In Rails4 How to assign variables in one controlle

2019-09-02 17:33发布

问题:

using Ruby on Rails 4, I have a UI where the user can select a video file from a directory path on a server. They then click a button that runs media info on the file and displays the xml for the video along with parsing certain data values from the xml and assigning the value to @variables and displaying it back in the UI html page. This is all done in the action/method 'evaluate media'. When the page loads back it determines if this file has been saved or not and allows the user to save the filename, path, and media info attributes to a table in mysql. When you click the save button it calls the acton/method 'save_file'. When I try to assign these variable values to the model class fields to insert into the table (within the controller). The values are not read. It only inserts nulls. How can I have these variable values assigned in the 'evaluate_media' action also be available for the 'save_file' action or any other action within the same controller? Based on how they were setup and defined, I thought they were availble within the scope of the model/controller object 'file_alias_tfile'.

In the 'save_file' action here are the 3 different ways I tried to assign the value:

    full_path = params[:filepath2]  <--This one puts a NULL into the table  
    src_location = @radio_button_value  <--This one puts a NULL into the table
    directory = "#{@dir_path_choice}"  <--This one doesn't even get called into the insert script and nothing is inthe column on insert. (I don't get errors and a record does geet inserted with the other good values.)into the table

Here is my save_file action/method code where I am trying to assign my variable values to the model fields:

  def save_file    

        src_location = @radio_button_value
        directory = "#{@dir_path_choice}"
        full_path = params[:filepath2]
 #       "#{@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')

@file_alias_tfile = FileAliasTfile.create(file_alias_tfile_params)

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 been saved."

# render = "index" end end

Here is the 'evaluate_media' method where the values called above in the save_file are defined:

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

 #Determine if file chosen has been saved to database yet.
 @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 = ""

   #Store selected value for re-display on post.
   @selected_filepath = params[:filepath2]

filepath = File.join(root_dir, provider_dir, params[:filepath])

   @filepath = File.join(params[:filepath2])  

   @media_xml = ::MediaInfo.call(@filepath)  #Filepath is sent in from the index html
   @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 = alias_parse_doc.elements.each("/aliasGenerator vr=/text()") { |e| e }
   @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 }   

   #parse Audio Media Info XML Doc 
  #  @audio_track = REXML::XPath.each(media_parse_doc, "//track[@type= 'Audio']/track/text()") { |element| element } 
 #   @track_array = REXML::XPath.each(media_parse_doc,(@audio_track)) do {|track| track.elements["Bit_rate"].text }
  #   @bitrate = track.elements["Bit_rate"].text
  #  end
    #@audio_tracknum = REXML::XPath.each(media_parse_doc, "//track[@type='Audio']/track streamid=/text()") { |element| element } 
   # @audio_format = REXML::XPath.each(media_parse_doc, "//track[@type='Audio']/Format/text()") { |element| element } 
   # @audio_bitrate = REXML::XPath.each(media_parse_doc, "//track[@type='Audio']/Bit_rate/text()") { |element| element }  
   # @audio_numchan = REXML::XPath.each(media_parse_doc, "//track[@type='Audio']/Width/text()") { |element| element } 
   # @audio_language = REXML::XPath.each(media_parse_doc, "//track[@type='Audio']/Display_aspect_ratio/text()") { |element| element } 

   render :action => :index

end

Can you please provide me an example of how I can either setup my variables correctly to pass across actions and/or how to properly assign them in the insert to the database?

Your help is appreciated!

回答1:

I found the answer in another question for my search but it still leaves an open question.

Here is the link for the other question and answer for more details: Same instance variable for all actions of a controller

Basically it gave me 2 approaches. If my one action is not rendering from the other, and both methods need to access the values, then I will need to define another method where I assign the variables and then have both save_file and evaluate_media methods call this newly define method so they too can access the variables. Here is the example where the question addressed the index and show methods sharing the same variable.

def index
  set_up_instance_variable
end

def show
  set_up_instance_variable
end

private

def set_up_instance_variable
  @some_instance_variable = foo
end

The other solution is using the before_filter:

You can define instance variables for multiple actions by using a before filter, e.g.:

class FooController < ApplicationController
  before_filter :common_content, :only => [:index, :show]

 def common_content
    @some_instance_variable = :foo
  end
end

Now @some_instance_variable will be accessible from all templates (including partials) rendered from the index or show actions.