Rendering form in comment controller - ruby-on-rails

I am trying to render my questions form partial on my posts show page. Right now when i enter text and press post it redirects to the default form and keeps the text.
I am rendering the form like so:
<%= render :partial => "questions/form", :locals => {:question => #comment.questions.new} %>
The questions controller:
def create
#comment = Comment.find(params[:comment_id])
#question = #comment.questions.new(question_params)
end
the form:
<%= simple_form_for [#comment, Question.new] do |f| %>

<%= render :partial => "questions/form", :locals => {:question => #comment.questions.new} %>
this part , :locals => {:question => #comment.questions.new} seems to be useless cause you override it anyway in the form partial with Question.new in the simple_form_for.
create action should have a save call and redirect to somewhere if save successfull or not.
def create
#comment = Comment.find(params[:comment_id])
#question = #comment.questions.new(question_params)
if #comment.save
redirect_to :back
else
# somet actions here
end
end

Related

Update database using 'update_attributes' through 'has_many'

I'm having a problem getting my first app (I'm a total newbie) to save a new associated record. I have two models (users and pictures) with a has_many/belongs_to association. I have set up the userController so that it can create a new picture as below:
def new_picture
#user = User.find(current_user.id)
#picture = #user.pictures.build
end
def create_picture
#user = User.find(params[:id])
#picture = #user.pictures.build(params[:picture])
if #picture.save
flash[:notice] = "Your picture was successfully added."
redirect_to :action => 'show', :id => #user.id
else
render :template => "new_picture"
end
end
and I use
<%= link_to("add picture", :action => 'new_picture', :id => #user.id) if current_user %>
to add a new one. But I'd also like to be able to edit. So I updated the usercontroller with some new code:
def edit_picture
#user = User.find(current_user.id)
#picture = #user.pictures.find(params[:id])
end
# When the user clicks the save button update record
def update_picture
#user = User.find(current_user.id)
#picture = #user.pictures.find(params[:picture])
respond_to do |format|
if #picture.update_attributes(params[:picture])
flash[:notice] = "Your picture was successfully updated."
redirect_to :action => 'show', :id => #user.id
else
render :template => "new_picture"
end
end
end
and added the edit link to show.erb:
<%= link_to("edit picture", :action => 'edit_picture', :id => picture.id) if current_user %>
It loads the edit form fine, with the data all in the right place, but on save all it's doing is giving me the error 'ArgumentError in UsersController#update_picture' with a bunch of Unknown key(s) from my pictures table.
Could somebody explain why? I feel like there is one piece of the jigsaw I haven't quite understood here....
Thanks in advance!
UPDATE: View code is as follows:
<h1>New picture for <%= #user.name %></h1>
<% form_for :picture, #picture, :html => { :multipart => true }, :url => {:action => 'update_picture', :id => #user.id} do |f| %>
Can't seem to see your problem in the view code, however you can do the same thing more elegantly (RESTful) as a nested route. That way you might be able to see the problem more clearly.
config/routes.rb:
resources :users do
member do
resources :pictures
end
end
app/controllers/pictures_controller.rb:
class PicturesController < ApplicationController
before_filter :find_picture, :only => [:edit, :update]
def edit
end
def update
if #picture.update_attributes params[:picture]
flash[:notice] = "Your picture was successfully updated."
redirect_to user_path(current_user)
else
render :edit
end
end
protected
def find_picture
#picture = current_user.pictures.find params[:id]
end
end
app/views/pictures/edit.html.erb:
<%= form_for [current_user, #picture] do |f| %>
<!-- some stuff -->
<% end %>
and to link to your edit form:
<%= link_to_if current_user, 'edit picture',
edit_user_picture_path(:user => current_user, :id => picture) %>
I suggest adding 'accepts_nested_attributes_for :pictures to the user model, and then do
<%= form_for #user do |form| %>
.. user fields
<%= form.fields_for :pictures do |picture_form| %>
.. picture fields
<% end %>
<%= form.submit %>
<% end %>
in the view.
Another option is to create a new controller for the pictures. That may be simpler.

Why can't I build more than one nested attribute here?

this is my form code:
<%= simple_form_for setup_video(#video) do |f| %>
<% f.fields_for :comment_titles do |t| %>
<%= t.input :title, :label => "Comment Title:" %>
<%= t.button :submit, :value => 'Add', :id => 'add_comment_title' %>
<div class='hint'>Let your listeners know what comments you want by adding a guiding title for them. Pose a question, ask for feedback, or anything else!</div>
<% end %>
<% end %>
I have has_many :comment_titles and accepts_nested_attributes_for :comment_titles, :comments in my model. when I create a new comment_title in the form, the old one is replaced. I want an additional one to be built. How can I do this?
Here are the video controller actions:
def new
#video = Video.new
respond_to do |format|
format.js do
render_to_facebox(:partial => 'add_video')
end
end
end
def create
#video = current_user.videos.new(params[:video])
respond_to do |format|
if #video.save
format.html { redirect_to(#video) }
else
format.html { render :action => "new" }
end
end
end
I think this is actually what is needed:
def update
#video = current_user.videos.find(params[:id])
respond_to do |format|
if #video.update_attributes(params[:video])
format.html { redirect_to(#video) }
format.js
else
format.html { render :action => "edit" }
end
end
end
The edit action here will provide a form which will allow you to edit the existing record as well as its nested attributes. This is why it's replacing the existing object.
If you only want people to add new comment titles then I would recommend building a new object in your edit action like this:
def edit
video = current_user.videos.find(params[:id])
video.comment_titles.build
end
Then this will be available as an additional row in your fields_for call. To only make this show new objects:
<% f.fields_for :comment_titles do |t| %>
<% if t.object.new_record? %>
# stuff goes here
<% end %>
<% end %>
However this restricts people to being able to only add new items in an edit action, which may seen counter-intuitive to some users.

Rails, Posting to a Custom Method

in my group controller I have two methods:
def new
#group = Group.new
respond_to do |format|
format.js
end
end
def new_beta
#group = Group.new
respond_to do |format|
format.js
end
end
I have a form that starts like so:
<%= form_for Group.new, :remote => true do |f| %>
How can I get the form_for to post to the new_beta controller? Thanks
You can set :
<%= form_for Group.new, :url=>{ :action =>"new_beta", :controller =>
"group"}, :remote => true do |f| %>
(you can also -preferably- directly use a named route instead of ":url => ")
First this is bad practice but..
in your routes add
resources :groups do
member do
get :new_beta
post :new_beta_create
end
end
Now
<%= form_for Group.new, :url => new_beta_create_groups_path, :remote => true do |f| %>
However I recommend creating a new controller called something like: alternate_groups_controller. Even better make a namespace for them.
Good luck

Rails 3 form_for ajax call

I have method in my controller:
def work_here
#company = Company.find(params[:id])
current_user.work_apply(current_user, #company)
redirect_to company_path
end
On my view:
<%= render 'companies/work_form' if signed_in? %>
_work_form.html.erb:
<%= form_for company, :remote => true, :url => { :controller => "companies", :action => "work_here" } do |f| %>
<%= f.hidden_field :id, :value => company.id %>
<%= f.submit "I working here" %>
<% end %>
And I have a work_here.js.erb file:
$("#work_at_form").html("<%= escape_javascript("render('companies/works')") %>")
But my form works without ajax request(in other pages ajax forks fine), my js.erb file never use.
Can anyone give me advise?
Thanks.
The work_here.js.erb can't be read because you never call it. A redirect is allways do. render it when the request is js format.
def work_here
#company = Company.find(params[:id])
current_user.work_apply(current_user, #company)
respond_to do |format|
format.html { redirect_to company_path }
format.js { render }
end
end

Rails 3 - Creating a comment and then returning the Partial with JUST the new comment

Here's the flow I have...
First, jquery posts the new comment to the server:
$.post(this.action,$(this).serialize(),null,'script');
Then in the comments controller:
def create
#comment = lots of stuff going on here but it works...
if #comment.save
flash[:notice] = "Successfully created comment."
respond_to do |format|
format.js
end
end
Ok and this is where I'm stuck, then the create.js.erb:
$(".cmtBox").html("<%=escape_javascript(render :partial =>"comments/comment")%>");
And the partial:
<div class="cmtBox" id="comment_<%=comment.id%>">
<%=comment.content%>
</div>
Where I'm stuck is calling the partial in create.js.erb... How do I pass what Rails needs to populate the partial? Right now I get the error: "Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id"
Thanks!
You should use:
render :partial => #comment
or
render :partial => "comments/comment", :object => #comment
or
render :partial => "comments/comment", :locals => {:comment => #comment}

Resources