Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export Invalid .xlsx file in Api only mode #107

Closed
NickBeukema opened this issue Sep 27, 2018 · 11 comments
Closed

Export Invalid .xlsx file in Api only mode #107

NickBeukema opened this issue Sep 27, 2018 · 11 comments

Comments

@NickBeukema
Copy link

I have created a base repo:
https://github.com/NickBeukema/axlsx_rails_testing

For both regular and api only mode, for both have done the following

  • Generate App and Lead model with properties Name and Occupation
  • Create LeadsController with index method, add resources :leads to routes file
  • Create views/leads/index.xlsx.axlsx file for rendering the .xlsx file

I visit the url and the api only version exports the file as 1 byte and cannot be opened, while the non api only version exports the excel file normally.

To reproduce the two repos, do the following:

  1. Clone and bundle
  2. rails db:migrate db:seed
  3. rails s
  4. Visit localhost:3000/leads.xlsx

I've also added a json responder to assure that the data is there and the respond_to function is working, so you can visit localhost:3000/leads.json to see the json data.

Do you know what dependencies I'm missing in the api only version? I've already included ActionController::MimeResponds to allow for respond_to usage. Any help would be great!

@straydogstudio
Copy link
Collaborator

Thanks! I'll take a look. I don't remember the differences off the top of my head.

@straydogstudio
Copy link
Collaborator

@NickBeukema I've spent some time looking at this and found the axlsx_rails template handler is not being called by the api even though the renderer is. I'll have to spend more time when I can digging into Rails itself to find the error. Have you tried this with rails 5.1 or earlier?

@straydogstudio
Copy link
Collaborator

Also I notice the api is rails 5.1.4 and the regular is 5.2.1. Did you just create a generic api?

@fresh2nd
Copy link

fresh2nd commented Oct 16, 2018

Same issue here.
Do you know what we need to add?
I am using rails 5.1.6 and created it in API Mode

@NickBeukema
Copy link
Author

For now I just made my application_controller.rb class inherit from ActionController::Base instead of ActionController::API.

From

class ApplicationController < ActionController::API
...

to

class ApplicationController < ActionController::Base
...

@straydogstudio
Copy link
Collaborator

I’ve spent a few hours in this. Hopefully I will get some more time this week. It is deep in the inheritance tree.

@straydogstudio
Copy link
Collaborator

straydogstudio commented Oct 27, 2018

@NickBeukema @fresh2nd
As I expected, Rails in API mode does not include the template loading mechanism. This is by design of course, since api does not include ActionView. See the difference in render_to_body between action_view/rendering.rb and action_controller/api/api_rendering.rb.

I would do one of two things:

  • If the templates aren't shared with another application, I would enclose the template code in a helper object and use it to produce the spreadsheet and stream it. You can see the code that is wrapped around the template here. Then I would simply serve the result from the controller.
  • If the templates have to be shared, I would try to adapt this script example and see if I could adapt it. That shows what must be included.

If either of you do so, consider adding a pull request for the README. Or drop it here. I will do it at some point.

@DonaldChiang
Copy link

Based on this issue: rails/rails#27211
Override render_to_body method in your API mode controller

class TestController < ActionController::API
  include ActionView::Rendering

  def show
    respond_to do |format|
      format.xlsx
    end
  end

  private

  def render_to_body(options)
    _render_to_body_with_renderer(options) || super
  end
end

And now you can export correct xlsx file, but still need better solution here.

@straydogstudio
Copy link
Collaborator

@DonaldChiang Did you ever find a better solution? What kind of solution were you imagining?

@straydogstudio
Copy link
Collaborator

Closing after adding this to the readme.

@straydogstudio
Copy link
Collaborator

There is another possibility. If you only have a Rails API, you really don't need to organize the code in templates. Instead consider using service classes to organize your code. Or something similar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants