简体   繁体   中英

How can I use a function defined in a controller in rails in a rake task?

I have an API function defined in my rails controller, and another to my database that I create using scaffold. `

  def function
    @results = HTTParty.get( $baseurl + "/extention", :headers => {
      $apikey => $apivalue,
      "Content-Type" => "application/json"
    })
    render json: @results.body
  end

`

I have defined a rake task that is executed with clockwork but to make it work in the current development environment I had to use httparty to call it internally and work with the received hash. `

  def rake_function
    @results = HTTParty.get("http://localhost:3000/controller/extension/")
    return @results.parsed_response
  end

In addition, my task makes a post and a put when the execution is finished and I must also use a httparty for that.

    if (!datExist)
        @response = HTTParty.post("http://localhost:3000/controller/extension/",
        body: eodData
        )
    else (datExist)
        checkId = dbData.select {|x| x["date_time"] == yesterday}
        id = checkId[0]["id"].to_s
        @response = HTTParty.put("http://localhost:3000/controller/extension/" + id,
        body: eodData
        )
    end

`

I know it's not the optimal way so I would like to be able to execute the function already defined in my controllers in my rake task

You don't.

The only public methods of your controller should be the "actions" that are called by the Rails router when it responds to HTTP requests.

Controllers are Rack applications and have a hard dependency on a incoming HTTP request - they just don't work outside of that context like in Rake task and using your controllers as a junk drawer leads to the "Fat Controller" anti-pattern.

Controllers already have tons of responsibilites - they are basically stiching your entire application together by passing user input to models and models to views. Don't give them more jobs to do.

Its a very easy problem to avoid by simply moving your API calls into their own class. One way of designing this is through client classes which are just resposible for communicating with the API:

class MyApiClient
  include HTTParty
  format :json
  base_url $baseurl # Code smell - avoid the use of globals
  attr_reader :api_key, :api_value

  def initalize(api_key:, api_value:)
    @api_key = api_key
    @api_value = api_value
  end

  def get_extension
    # I don't get why you think you need to dynamically set the header key
    self.class.get('extension', headers: { api_key => api_value })
  end
end

This lets you simply re-use the code between your controller and rake task and isolates the code touching the application boundy which avoids creating a tight coupling between your application and the external collaborator.

HTTParty also really shines when you actually use it for object oriented and not proceedural code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM