How to redirect_to(:back) two times? - ruby-on-rails

def update
if #note.update_attributes(note_params)
redirect_to :back, notice: "Note was updated."
else
render :edit
end
end
Is there a way to redirect back twice?

Here you go:
This is where the link for editing goes:
<p id="notice"><%= notice %></p>
<% url = "#{request.protocol}#{request.host_with_port}#{request.fullpath}" %>
<%= link_to 'Create New Page and Return Here', edit_page_path(1, :url => Base64.encode64(url) ) %>
<br>
After submit your url will be something like this:
http://localhost:3000/pages/1/edit?url=aHR0cDovL2xvY2FsaG9zdDozMDAwL2R1bW1pZXM%3D%0A
In the edit form:
I called it pages/_form.html.erb, Pass the URL as a hidden params.
<%= form_for(#page) do |f| %>
<% if #page.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#page.errors.count, "error") %> prohibited this page from being saved:</h2>
<ul>
<% #page.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :permalink %><br>
<%= f.text_field :permalink %>
</div>
<%= hidden_field_tag :url, params[:url].to_s %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
In controller that you have update method, in this case pages_controller.rb, simply Base64 it back and redirect the user:
def update
redirection = nil
if params[:url].present?
redirection = Base64.decode64(params[:url].to_s)
end
if #page.update(page_params)
if redirection.present?
path = redirection
else
path = #page
end
redirect_to path, notice: 'All Done.'
else
render :edit
end
end
Now user updates the form and redirected back to the first show or index page or any page that she is coming from.
Hope this help.
PS: You might want to clean it up a bit and pass the url from the controller, and put some checks on it. So you don't define any var at the view level. In the above code I just tried to solve this issue not really a design pattern oriented :)

Related

Instance variable nil in one view, not in another

I'm working on a project in Ruby on Rails (Ruby v.2.2.8, Rails 5.1.4) and have encountered a very strange issue.
For my show method in the controller, I have:
def show
#county = County.find(params[:id])
end
And it works. For update, I have.
def update
#county = County.find(params[:id])
if #county.update(county_params)
redirect_to #county
else
render 'edit'
end
end
In my 'edit', I consistently get an error that #county is nil. The error page indicates that the parameters are being passed as:
{'id'=>4}
as an example. When I use find_by from the rails console, the item is found.
Is there something here I'm missing?
ETA: View Code
<%= form_with model: #county, local: true do |form| %>
<% if #county.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#county.errors.count, "error") %> prohibited
this county from being saved:
</h2>
<ul>
<% #county.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= form.label :name %><br>
<%= form.text_field :name %>
</p>
<p>
<%= form.label :shortname %><br>
<%= form.text_field :shortname %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
ETA Routes for Counties:
counties GET /counties(.:format) counties#index
POST /counties(.:format) counties#create
new_county GET /counties/new(.:format) counties#new
edit_county GET /counties/:id/edit(.:format) counties#edit
county GET /counties/:id(.:format) counties#show
PATCH /counties/:id(.:format) counties#update
PUT /counties/:id(.:format) counties#update
DELETE /counties/:id(.:format) counties#destroy
The error occurs at /counties/:id/edit
How is your edit action in your controller?
You should define #county as well
def edit
#county = County.find(params[:id])
end

How to set up Edit for Remote Form in Rails?

Webpage View
So in the image button above, I have a button called "Mark Item as Done". Inside that Item table, I have a date: due_date, string: task_title, text: description, and a boolean: done.
Now I put the format.js in the todoitems_controller.rb because I figured that would be the best place to put it because I'm calling their edit link
todolist_todoitems GET /todolists/:todolist_id/todoitems(.:format) todoitems#index
POST /todolists/:todolist_id/todoitems(.:format) todoitems#create
new_todolist_todoitem GET /todolists/:todolist_id/todoitems/new(.:format) todoitems#new
edit_todolist_todoitem GET /todolists/:todolist_id/todoitems/:id/edit(.:format) todoitems#edit
todolist_todoitem GET /todolists/:todolist_id/todoitems/:id(.:format) todoitems#show
PATCH /todolists/:todolist_id/todoitems/:id(.:format) todoitems#update
PUT /todolists/:todolist_id/todoitems/:id(.:format) todoitems#update
DELETE /todolists/:todolist_id/todoitems/:id(.:format) todoitems#destroy
todolists GET /todolists(.:format) todolists#index
POST /todolists(.:format) todolists#create
new_todolist GET /todolists/new(.:format) todolists#new
edit_todolist GET /todolists/:id/edit(.:format) todolists#edit
todolist GET /todolists/:id(.:format) todolists#show
PATCH /todolists/:id(.:format) todolists#update
PUT /todolists/:id(.:format) todolists#update
DELETE /todolists/:id(.:format) todolists#destroy
root GET / todolists#index
Now, should I also be doing something to the def edit in the todoitems_controller.rb as well or just def update? And putting remote: true in the Todolists/_form.html.erb file, is it the best place to put it there or should I put it in Todoitems/_form.html.erb file? And after doing all these, what is the next step?
This is what I've managed to accomplish so far and this is my first time working with remote forms. I'm just struggling to get this started because the lectures are confusing. If there's anything else missing, I'm happy to provide more info about this! Any help would be appreciated!
todolists/show.html.erb - Look at button_to. That's the part I need help
<p>
<% #paginate_items.each do |item| %>
<div class="list">
<form class="oneLine">
<a class="notDue">
<%= item.due_date %>
</a>
<a class="linkResults">
<%= link_to "#{item.task_title}", [#todolist, item], style: "font-weight: bold;" %>
<%= button_to "Mark Item as Done", remote: true %><br/> <br/>
</a>
</form>
<% end %>
todoitems_controller.rb - I already put the render.js in the update.
def update
respond_to do |format|
if #todoitem.update(todoitem_params)
format.html { redirect_to #todolist, notice: 'Item was successfully updated.' }
format.json { render :show, status: :ok, location: #todoitem }
render.js
else
format.html { render :edit }
format.json { render json: #todoitem.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_todoitem
#todoitem = Todoitem.find(params[:id])
end
def set_todolist
#todolist = Todolist.find(params[:todolist_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def todoitem_params
params.require(:todoitem).permit(:due_date, :task_title, :description, :done, :todolist_id)
end
todolists/_form.html.erb - I already put the remote: true
<body class="page">
<%= form_for(#todolist, remote: true) do |f| %>
<% if #todolist.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#todolist.errors.count, "error") %> prohibited this todolist from being saved:</h2>
<ul>
<% #todolist.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :list_name %><br>
<%= f.text_field :list_name %>
</div>
<br/>
<div class="field">
<%= f.label :list_due_date %><br>
<%= f.text_field :list_due_date, class: 'dateSelect' %>
</div>
<br/>
<div class="actions">
<%= f.submit %>
</div>
<br/>
<% end %>
</body>
todoitems/_form.html.erb
<body class="page">
<%= form_for([#todolist, #todoitem], remote: true) do |f| %>
<% if #todoitem.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#todoitem.errors.count, "error") %> prohibited this todoitem from being saved:</h2>
<ul>
<% #todoitem.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :due_date %><br>
<%= f.text_field :due_date, class: 'dateSelect' %>
</div>
<br/>
<div class="field">
<%= f.label :task_title %><br>
<%= f.text_field :task_title %>
</div>
<br/>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description, size: "40x10" %>
</div>
<br/>
<% if !#todoitem.new_record? %>
<div class="field">
<%= f.label :done, 'Task Completed' %>
<%= f.check_box :done %>
</div>
<br/>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<br/>
<% end %>
</body>
You haven't provided all the parameters to button_to to make the form work. This helper method generates a form and you need to provide the path for the form to POST to. Have a look at the docs for the button_to helper to see what you're missing.
<%= button_to "Mark Item as Done", todolist_todoitem_path(#todolist, #todoitem), method: patch, remote_true %>
(I'm not sure what your routes are so I made it up.)
When you're updating a resource you need to provide the method (either patch or put is for updating). You might want to read up on routing as well. Initially, they can be a little confusing, but they are at the heart of an interactive rails application so understanding them is key.

Getting "param is missing or the value is empty: post" explained below

when i click new post and try to save a new post it gives me that error, then i go to the controller :
private
def posts_params
params.require(:post).permit(:title, :description)
end
and change 'require(:post)' to 'require(:posts' then i works
but then i try to edit the new post i just created and when i click to save it it gives me the same error, then i just change it back to 'required(:post)' and it works, why this is happening ? it's like a loop, if one works the other doesn't and to work i have to change that one thing
Controller:
class PostsController < ApplicationController
def index
#posts = Post.all
end
def edit
#posts = Post.find(params[:id])
end
def update
#posts = Post.find(params[:id])
if #posts.update(posts_params)
redirect_to #posts
else
render 'edit'
end
end
def new
#posts = Post.new
end
def create
#posts = Post.new(posts_params)
if #posts.save
redirect_to #posts
else
render 'new'
end
end
def show
#posts = Post.find(params[:id])
end
private
def posts_params
params.require(:post).permit(:title, :description)
end
end
view edit:
<h1>Editing post</h1>
<%= form_for(#posts) do |f| %>
<% if #posts.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#posts.errors.count, "error") %> prohibited
this post from being saved:
</h2>
<ul>
<% #posts.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :description %><br>
<%= f.text_area :description %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Back', posts_path %>
view new:
<h1>New Article</h1>
<%= form_for :posts, url: posts_path do |f| %>
<% if #posts.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#posts.errors.count, "error") %> prohibited
this post from being saved:
</h2>
<ul>
<% #posts.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :description %><br>
<%= f.text_area :description %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Back', posts_path %>
can someone point the problem out ?
You are mixing
form_for(#posts) do |f|
and
form_for :posts, url: posts_path
In your forms.
the :posts version will generate params[:posts] and the #posts version will generate params[:post]. Hence the issue you are seeing. Make sure you posts_params is as follows.
def posts_params
params.require(:post).permit(:title, :description)
end
then just change both of your forms to be
<%= form_for(#posts) do |f| %>
rails will figure out which to call automatically for you, so you will not have to specify the paths..
On a side note, I would probably change #posts to be #post everywhere but the index action, just so that it makes more sense, Since in new,edit,etc.. you are dealing with a singular post.
Since rails is looking at the Model/class of the variable when generating the routes (When given an instance variable) the name of the variable doesn't matter to the framework, but makes it easier (in my opinion) for the programmer to understand

Rails: Hidden fields not passing values

I am trying to create a form for a site administrator to associate events with a list of previous speakers. The administrator navigates to the speaker, clicks on a button to "Add to event" and a form comes up asking for which event the speaker is attending. The speaker is supposed to be passed in as a hidden field, and the events are listed via a collection select. Unfortunately, the speaker id is not passing into the database when I submit the form.
Why is my form is not saving values from the hidden field, and how do I about fixing this? Values from the collection select are passing.
<%= form_for(#event_speaker) do |f| %>
<% if #event_speaker.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#event_speaker.errors.count, "error") %> prohibited this event_speaker from being saved:</h2>
<ul>
<% #event_speaker.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p><%= #speaker.first_name %></p>
<div class="actions">
<%= #speaker.id %>
<%= f.hidden_field(:speaker) %>
<%= hidden_field_tag('speaker_id',#speaker.id) %>
</div>
<div class="field">
<%= f.label :event %><br>
<%= f.collection_select(:event_id, #upcoming_events, :id, :name)%>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And the controller:
def new
#event_speaker = EventSpeaker.new
#speaker = Speaker.find(params[:speaker_id])
#event_speaker.speaker_id = #speaker
#Time = Time.now
#upcoming_events = Event.all
end
# GET /event_speakers/1/edit
def edit
end
# POST /event_speakers
# POST /event_speakers.json
def create
#event_speaker = EventSpeaker.new(event_speaker_params)
respond_to do |format|
if #event_speaker.save
format.html { redirect_to #event_speaker, notice: 'Event speaker was successfully created.' }
format.json { render action: 'show', status: :created, location: #event_speaker }
else
format.html { render action: 'new' }
format.json { render json: #event_speaker.errors, status: :unprocessable_entity }
end
end
end
And...
def event_speaker_params
params.require(:event_speaker).permit(:speaker_id,:event_id)
end
You should do
<%= f.hidden_field :speaker_id, :value => #speaker.id %>
This will generate your speaker_id nested inside event_speaker so your form will look like this:
<%= form_for(#event_speaker) do |f| %>
<% if #event_speaker.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#event_speaker.errors.count, "error") %> prohibited this event_speaker from being saved:</h2>
<ul>
<% #event_speaker.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p><%= #speaker.first_name %></p>
<div class="actions">
<%= f.hidden_field :speaker_id, :value => #speaker.id %>
</div>
<div class="field">
<%= f.label :event %><br>
<%= f.collection_select(:event_id, #upcoming_events, :id, :name)%>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
For details checkout hidden field in rails

Using a form to populate a database and land on a page with the information submitted

I have a form on my new view that takes in "url" and "title". When I submit my "url" & "title" I am taken to a blank create view. Ideally I would like to populate my database and land on a page that shows the title and link for that project.
This is my controller as it stands:
class LinksController < ApplicationController
def index
end
def new
#link = Link.new
end
def create
end
end
And this is the form:
<h1> This is New page for links </h1>
<%= form_for(#link) do |f| %>
<% if #link.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#link.errors.count, "error") %> prohibited this link from being saved:</h2>
<ul>
<% #link.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :url %><br />
<%= f.text_field :url %>
</div>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
How would I go about creating my methods(actions) to populate the database and then render what I am seeking? Ideally I'd like to see the flow behind how to think about the problem and the final code so that I can reverse engineer it.As long as I see it once I should be able to do it on my own next time.
You just have to do this
def create
#link = Link.new(params[:link])
if #link.save
redirect_to #link
else
render :new
end
end
def show
#link = Link.find(param[:id])
end
In routes.rb you will want to make sure you have the routes for this controller and its actions.
resources :links
That will provide you the standard CRUD HTTP methods with matching routes.

Resources