简体   繁体   中英

Ruby on Rails: how to render a view from same controller but with a different route?

I have a controller, farms_controller , that is being used for two different routes, farms and person_farms ; the two routes use the same folder for view templates (ie, new_person_farm_path and new_farm_path use the same template, new.html.erb ). I want to access the farms register pages both separately and inside the person register, where some functionalities are different using the URL in some tests to show different functionalities (via request.env['PATH_INFO'].include? 'person_farms' , because I don't know a best way).

When I submit without the required fields (name) from the new_person_farm_path , the create function renders the new_farm_path page with a different styling for incorrect fields (using the 'twitter-bootstrap-rails' gem). I want it to instead render the new_person_farm_path page, with the same template file but a different routing (different URL). I tried to use redirect_to and it shows the page in the correct URL, but not the styling in the wrong fields.

However, all the instructions I saw in Rails documentation for rendering are above rendering a specific file, but it's not what I need. I have a feeling that it's not the "Rails way", but I'm a starter on RoR and this a legacy system that is being rewritten to Rails, so I can't correct the DB logic for now.

So, is there a way to render a view from same controller but with a different route?


My code:

def create
  @farm = Farm.new(farm_params)
  respond_to do |format|
    if @farm.save
      # Param sent by the page to test if I'm in a person_farms page
      # instead of a farms page because the request.env test doesn't work here.
      # I feel that this is not the correct way to do that, but I can leave the correct way to another question.
      # However, if someone has a suggestion a comment would be appreciated.
      if params[:is_person_farm_page]
        format.html { redirect_to @person_farm_path(@farm), notice: 'Farm saved' }
        format.json { render :show, status: :created, location: @farm }
      else
        format.html { redirect_to @farm, notice: 'Farm saved' }
        format.json { render :show, status: :created, location: @farm }
      end
    else
      #This is the point where I want to redirect to new_person_farm_path
      #I would need to test using the params[:is_person_farm_page] above
      format.html { render :new }
      format.json { render json: @farm.errors, status: :unprocessable_entity }
    end
  end
end

Send parameters in the path like:

new_person_farm_path(param_1: 'my param')

And then in the controller you can access that value with:

params[:param_1]

And pass it to your view as an instance variable or (if you are using) a view object:

@show_some_part = params[:param_1].present? # This can be a boolean or something else

Now in your view you can ask for that value

<%= something if @show_some_part %>

For solving my specific problem (redirect to the correct new page but with the error fields), I did this solution (probably not the best if you are doing it from the start, but I was already with many functionalities working, and I wanted to keep the person_farm_path and farm_path as different URLs):

In my controller, I used the first answer to this thread: Rails: I cant pass a validation error in a redirect , and so I inserted this code in the create action:

if @farm.save
  ... #the same code in my question
else
  if params[:is_person_farm_page]
    #pass the errors messages via flash, "imploding" the array of errors into a string
    format.html { redirect_to new_person_farm_path, :flash => { :error => flash_errors = @farm.errors.full_messages.join(',')}}
    format.json { render json: @farm.errors, status: :unprocessable_entity }
  else
    format.html { render :new }
    format.json { render json: @farm.errors, status: :unprocessable_entity }
  end
end

Now I'm able to pass the errors through the redirect action, instead of the render action. Then, in the form.html.erb , I only need do "explode" the string sent in a new array:

<% errors_sent_via_flask = flash[:error] ? flash[:error].split(",") : [] %>

For seeing all the errors_message I can get, I used <%= errors_sent_via_flask .inspect %> (this echoes all array members in the page) and simulated the error situation and submitted the form. For example, the error message for a missing name field is something like "Farm name can't be blank".

Now I can check if the "Farm name can't be blank" error is happening using errors_sent_via_flask.include? "Farm name can't be blank" errors_sent_via_flask.include? "Farm name can't be blank" in the page.

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