I'm new to development on rails and I needed a bit of help
I was working on a project for cataloging projects in our college.
I have a controller and an associated model called projects. I would like to have a form_for in the Show page of projects.
Is that even possible?
If so, Any idea on how I can go about this?
Thanks
Yes, you can. First initialize your Model object in show method like this:
def show
#project = Project.new
end
and in your show.html.erb, use for_for like this:
<%= form_for #project do %>
##your form stuff
<% end %>
Hope it will help. Thanks
A good practice is usually to put your form inside a file of its own (partial), so if you need it in other places, you can easily use it
so, in a file named _form.html.erb (under the same folder where show.html.erb is), put your form code and then from the show.html.erb use
<%= render 'form' %>
Then you could use your from also from other views
Related
I have a model called sections, which has many feedbacks. This is working ok, and on the 'section' show page I can show the associated 'feedbacks' like so:
<% #section.feedbacks.each do |feedback| %>
<%= feedback.name %>
<%= link_to 'Show', feedback %>
<%= link_to 'Edit', edit_feedback_path(feedback) %> |
<% end %>
Works fine. But now I need a button that takes me to the create page for a new feedback item, and it needs to be associated to this 'section'.
At first I did it with a nested form, but the feedback items have quite a lot of fields and so it's messy to do it all on one page.
I'm new to ruby, so hopefully it's a really simple thing!
Thanks in advance for any help,
James
You should use nested form for it. If your form contains many fields then use bootstrap wizard for it.
or
<%= link_to 'New', new_feedback_path(section_id: #section.id) %>
& in your new method of feedback_controller , write the below:
#feedback = Feedback.new
#feedback.section_id = params[:section_id]
What you are trying to do is pretty much standard Rails stuff and you need to read a bit more of the official guides. You will need:
A controller with different actions for feedbacks (edit and new for example)
Some views for the above actions. The edit and new views can share the same form.
Routing to make it possible to work with a Feedback in the context of a Section.
Like:
resources :sections do
resources :feedbacks
end
This will allow you to use the following instead of your edit link:
<%= link_to 'Edit', edit_feedback_path([#section, feedback]) %>
And will go to this edit route:
/sections/:section_id/feedbacks/:feedback_id
You will also have the following new route available:
/sections/:section_id/feedbacks/new
Which will allow you to get the right section from the url params in order to create a feedback for it.
I have ideas controller and static_pages controller. The latter has home action which displays all ideas and which i also use as root path.
I want the user be able to Edit the displayed ideas. So far i have this:
<% if #ideas.empty? %>
<p>Share your ideas! See what people think about it.</p>
<% else %>
<% #ideas.each do |idea| %>
<div class="panel panel-default">
<div class="panel-heading"><%= idea.name %></div>
<div class="panel-body"><%= idea.description %> <br>
<%= link_to 'Edit', edit_idea_path(idea.id) %>
</div>
</div>
<% end %>
<% end %>
I had an issue with an empty idea id which i solved by adding idea.id inside edit_idea_path
Now my question is, is that the proper, Rails way of doing it? In what other way can i fetch the idea object from this index page and use it in my ideas controller instead of static_pages controller?
I tried playing around with routing, but I have very vague understanding of it despite reading the guides and others code. I'd appreciate any insight about this matter.
First you need to understand that the requirement of your project defines what you should do in the code, whithout of concerning about the proper way to do something. You just need to follow the rails conventions.
http://guides.rubyonrails.org/active_record_basics.html#convention-over-configuration-in-active-record
Now, back to your question. You just need to create an action (that will handle a view) in your ideas_controller that will manage the edition of the data sended by de static_pages_controller, i will call it (just for example) edit_static_ideas and receive the data with params:
In your ideas_controller : app/controllers/ideas_controller.rb
def edit_static_ideas
#idea = Idea.find(params[:id])
end
Then you need to create the view in your views->ideas folder. An name it, just to continue my example i'll name it edit_static_idea.html.erb. And set the load of the data you get in #idea as a form or a form_for. Then you can submit that edited data and upload it into other action.
Then you have to configure your routes file and add
config/routes.rb
get 'edit_static_idea/:id', to: 'ideas#edit_static_idea', as: 'edit_ideas'
After that, if you run "rake routes" in your console (inside your rails project), you should see your new route (yay!)
Now you have to take the path in your route and use it in you static_pages_controller's view to redirect it to the edit_idea's view handle it by ideas_controller. And be sure that you also send the id of the selected item.
app/views/static_pages/home.html.erb:
<%= link_to 'Edit Idea', insert_your_edit_idea_obtainedinrakeroutes_path(id: idea.id) %>
At last, you only need to configure the form in your edit_static_idea.html.erb and assign it an upload/save route and redirect it to the view that you want.
for example:
In your routes file: config/routes.rb
patch 'save_edited_idea', to: 'ideas#save_edited_idea', as: 'save_edited_idea'
In your ideas_controller: app/controllers/ideas_controller.rb
def save_edited_idea
#idea = Idea.find(params[:id])
respond_to do |format|
if #idea.update(idea_params)
format.html { redirect_to the_view_that_you_want_path(id: #idea.id), notice: 'Data saved without problems.' }
else
flash.now[:alert] = "error"
format.html { render :offer }
end
end
end
I didn't wanted to be so detailed, because i wanted to help you to understand what you have to do. I hope it helps :P
Ok, So i'm trying to place the form found in the "_form.html.erb" in the "index.html.erb" of my ruby project crashes with the error
"First argument in form cannot contain nil or be empty"
<%= form_for(#customer) do |f| %>
I know that changing the #customer to Customer.new could fix this but I would like to know why this isn't necessary in one file and it is in another
Why is this happening and how do I make a form that will update the sqlite db on the index page.
#customer is a variable that must be created somewhere in the corresponding controller action. If your #index controller action defines a variable by that name, then you'll be able to use it in the view template; otherwise you'll need to create it like this:
#customer = Customer.new # (or whatever the value is)
When Rails processes a request, it just executes a big (and complex) lump of code that's created from a bunch of different files. First it executes the appropriate controller action, then it executes any Ruby code found inside the corresponding view template. So any variable (or any method name) that is used in the view template, was first defined at some point before that: either in the controller action, or in one of Rails' countless built-in helper files.
When I am using form_for in a index or show page I like to do is set it to new
<%= form_for Customer.new, url: {controller: "customers", action: "create"} do |f| %>
...
<%= f.submit %>
<% end %>
that way there is a object to be created, I also I like to pass in the controller and the action.
I want to connect two entity (project and issues) and Rails says some error message, but I don't know, what should I do. Can you help me fix it, please? Thanks a lot.
Not sure what your are trying to do, but it looks like you have a nested resource and therefore want to pass an array to form_for, but you are actually passing two separate objects. Change:
<%= form_for(#project, #project.issues.build) do |f| %>
to:
<%= form_for([#project, #project.issues.build]) do |f| %>
With this change you'll pass one array for form_for, instead of two arguments.
I think you have used nested resources like this:
resources projects do
resources issues
end
If you used that, try make your form like this:
<%= form_for([#project, #issue]) do |f| %>
and in your IssueController :
def new
#project = Project.new
#issue = #project.issues.build(params[:issue])
end
def create
#project = Project.find(params[:project_id]
#issue = #project.issues.create(params[:issue]
end
and run again to see something happen. Hope this help.
So, I have a bunch of partners whose templates and images are stored below the view, public/images, public/stylesheets, public/javascripts directories.
For example, images for a partner 'foo' are stored in public/images/foo
This partner is an instance variable #partner which is accessible at the application level.
Problem is, I'm doing this all over the place: <%= image_tag "/images/#{#partner}/image.jpg" %> or within locations_controller: <% redirect_to "/locations/#{#partner}/index" %> ...
One reason for the load path part of the question rather than using helpers: we have to specifically <% render :template => "/locations/#{#partner}/index" %> since Rails looks in /locations/index by default.
How could I make this easier on myself? How could I add to load path once I have #partner?
Using Ruby 1.8.7 and Rails 2.3.4
Your redirection in the controller is really bad practice
you should do something like:
redirect_to get_path(#partner)
then in your controller
def get_path(partner)
case partner
when "partner1"
partner1_path
...
end
end
Concerning your pictures, you should create a helper.
def get_pic(partner, image)
image_tag "/images/#{partner}/#{image}"
end
And in your view
<%= get_pic(#partner, "image.jpg" %>