Editable txt files in the view

Hello friends,

I am a new player in rails and I have a problem. I would like to edit local txt files in views. The controller opens the file (File.open) and text_area_tag displays it. I have no idea or skills what to do next to save changes. Can you tell me something about this? ಥʖ̯ಥ

Greetings,

Ralph

First thing, this sounds like an excellent way to get your server hacked. So proceed with a lot of caution.

Second thing, Why? Databases are highly optimized for this sort of thing, and offer way more options for you down the road that a file storage will not (simultaneous, buffered read-write access, for one). Even if your goal is to edit the file so that it may be used as a file elsewhere, there are other ways to skin that cat, like offering a download path from a normal database-backed Rails view.

In broad strokes, you’re going to need a “sandbox” directory on your server where this file or files will be stored. Your File.open will need to be scoped to only open files within that directory. If you’re going to allow this to happen from the browser, and then allow that file to be displayed on the Web later, you’re going to have to ensure that proper sanitization is run on the result, either before writing back out to the file, or before displaying its contents either for reading or editing.

class TextsController
  before_action :get_file, only: [:show, :edit]
  after_action :close_file

  def show
    @text = @file.read
  end

  def edit
    @text = @file.read
  end

  def update
    get_file('w')
    @file.write sanitize params[:text]
    @file.close
    redirect_to texts_path(params[:file])
  end

  private

  def get_file(mode = 'r')
    @file = File.open(Rails.root.join('path', 'to', 'sandbox', "#{File.basename(params[:file])}.txt"), mode)
  end

  def close_file
    @file.close if @file
  end
end

# routes

get 'texts/:file', to: 'texts#show', as :text
get 'texts/:file/edit', to: 'texts#edit', as :edit_text
patch 'texts/:file', to: 'texts#update', as: 'text'
put 'texts/:file', to: 'texts#update', as: 'text'

Before you go to all this trouble, though, just try this:

rails generate scaffold Text name content:text

Then, run

rake db:migrate 

(if you’re not using SQLite, you’ll need to run rake db:create first)

Finally rails s and visit localhost:3000 in your browser. I think you’ll find something that fits your needs a lot better than editing a text file ever will.

Walter

1 Like