Rails - routing when nesting with rails - beginner - ruby-on-rails-3

I am relatively new to programming and to rails so please be indulgent:)
I am building a website for myself which contains a blog. I have two models that are nested and I do not seem to understand how to use REST to perform certain actions on my articles and comments.
When I create a comment if the comment doesn't pass validation I want it to render the page again so that the user can correct his mistakes and resubmit the comment. When I try to render, it gives me a missing template error.
Here is the code:
You can also find this code on github --> https://github.com/MariusLucianPop/mariuslp-
routes.rb
Mariuslp::Application.routes.draw do
get "categories/new"
root :to => "static_pages#index"
match "login" => "visitors#login" # not rest
match "logout" =>"visitors#logout" # not rest
match "comment" => "articles#show"
resources :articles do
resources :comments
end
resources :tags, :taggings, :visitors, :categories, :comments
end
articles_controller.rb
def show
#article = Article.find(params[:id])
#comment = #article.comments.new
end
comments_controller.rb
def create
article_id = params[:comment].delete(:article_id)
#comment = Comment.new(params[:comment])
#comment.article_id = article_id
if #comment.save
redirect_to article_path(#comment.article_id)
else
render article_path(#comment.article_id,#comment) ## This one doesn't work
end
end
def new
#comment = Comment.new
end
def destroy
Comment.find(params[:id]).destroy
redirect_to articles_path()
end
Views-articles:
_comment.html.erb
<div class="comment">
<%= comment.body %><br />
<%= link_to "Delete Comment", article_comment_path(#article), :method => :delete, :confirm => "Are you sure you want to delete this comment?" %>
</div>
_comment_form.html.erb
<%= form_for #comment do |f|%>
<%= f.hidden_field :article_id%>
<%= f.label :body %><br />
<%= f.text_area :body, :cols => 50, :rows => 6 %><br />
<%= f.submit%>
<%end%>
show.html.erb
<p><%= link_to "<< Back to Articles", articles_path%></p>
<div class = "article_show">
<%= label_tag :category_id %>
<%= #article.category_id%> <br />
<%= label_tag :title%>:
<%= #article.title%> <br />
<%= label_tag :body%>:
<%= #article.body%> <br />
<%= label_tag :tag_list%>:
<%= #article.tag_list%><br />
</div>
<br />
<% if session[:username]== "marius"%>
<div class ="admin">
<%= link_to "Edit", edit_article_path(#article)%>
<%= link_to "Delete", article_path(#article), :method => :delete, :confirm => "Are you sure you want to delete this article ?"%>
</div>
<%end%>
<br />
<%= render :partial => 'comment', :collection => #article.comments %>
<%= render :partial => 'comment_form'%>

Have you tried to use where you point the problem?
render 'articles/show'
You don't need to use article_comment_path because that is a full path, not just the place where you store the view templates. In this case, you only need the view. Of couse you must be sure to get all instance variable which you use in this views.
UPDATE:
#article = Articles.find(article_id)
render 'articles/show'

Related

Registration in Rails

I am attempting to create a new user in rails. There is a username, email, password and password confirm field on the new user form. When I click on the create user button on the web page, the new_user form simply refreshes and the user is not added to the database.
Here is the code for my register method in the authentication controller
def register
#user = User.new(params[:user])
if #user.valid?
#user.save
session[:user_id] = #user.id
flash[:notice] = 'Welcome.'
redirect_to sign_in_url
else
render :action => "new_user"
end
end
This is my new_user form:
<p>Sign Up</p>
<%= form_for #user, :as => :user, :url => new_user_path, :method => :put do |f| %>
<p>
<%= f.label 'username:' %><br/>
<%= f.text_field :username %>
<%= show_field_error(#user, :username) %>
</p>
<p>
<%= f.label 'email:' %><br/>
<%= f.text_field :email %>
<%= show_field_error(#user, :email) %>
</p>
<p>
<%= f.label 'password:' %><br/>
<%= f.password_field :password %>
<%= show_field_error(#user, :password) %>
</p>
<p>
<%= f.label 'password confirmation:' %><br/>
<%= f.password_field :password_confirmation %>
<%= show_field_error(#user, :password_confirmation) %>
</p>
<p>
<%= f.submit 'Sign Up' %>
<%= f.submit 'Clear Form', :type => 'reset' %>
</p>
Can anybody point me in the right direction?
Your call to new_user_path in your form references the url to User#new if you have defined resources :users in your routes.rb file. You will need to replace new_user_path with register_user_path, if you have defined register in your routes file. Double check for the path with by running rake routes, though.
From what I can see, there is no need to use have the register action. It'd make more sense to use RESTful actions new, create, index, show, edit, update, and destroy in your case, since your logic follows the intuition behind them. Rails makes this convention easy to follow. See the routing Rails guide here for more.

rails form partial for new and edit on same page

I am running into issues trying to separate a form from a view into a partial. I want to use the same form for the new and edit views. These are both on the same page. The new model form is at the top of the page and uses a variable that I set in the controller.
<%= form_for #new_hire do |f| %>
<%= render :partial => 'new_hire_requests/form', :locals => {:f => f} %>
<% end %>
I then have a partial for the pending approvals that gets rendered by another partial
<%= render :partial => 'pending_approval', :collection => #pending_approval %>
And inside the pending approval partial I have this
<%= form_for pending_approval do |f| %>
<%= render :partial => 'new_hire_requests/form', :locals => {:f => f} %>
<% end %>
This is throwing an error
undefined method `new_hire_request_path' for #<#<Class:0x0000010488ac98>:0x0000010223ffc0>
Is there a way to re use the form code for both a new and edit form on the same page?
Controller Logic
#new_hire = NewHireRequest.new
#new_hire_requests = current_user.new_hire_requests
#pending_approval = #new_hire_requests.select{|p| p.status == 'pending_hr_approval' || p.status == 'pending_exec_approval'}
Partial code
<%= render 'shared/error_messages', object: f.object %>
<fieldset class="first">
<%= f.label :first_name, "First Name" %>
<%= f.text_field :first_name %>
</fieldset>
<fieldset>
<%= f.label :last_name, "Last Name" %>
<%= f.text_field :last_name %>
</fieldset>
<%= f.submit "Submit for Approval <i class='icon-share-alt icon-white'></i>",
class: "button_green" %>
add resources new_hire_requests in the routes and get done with it .

ruby on rails form and passing its parameter to controller

When the view pass the parameters to controller,
controller gets nil for all of the arguements somehow.
Can anyone how to fix this?? Thanks!
and I have no model called "Message"
controllers/messages_controller.rb
def deliver
recipient = User.find_by_username(params[:recipient])
subject = params[:subject]
body = params[:body]
current_user.send_message(recipient, body, subject)
redirect_to :controller => 'messages', :action => 'received'
flash[:notice] = "message sent!"
end
views/messages/new.html.erb
<%=form_for :messages, url: url_for( :controller => :messages, :action => :deliver ) do |f| %>
<div class="field">
<%= f.label :subject %><br />
<%= f.text_field :subject %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_field :body %>
</div>
<div class="actions">
<%= f.submit %>
<% end %>
Check your source HTML to better understand what FormHelpers do.
With the form_for f.text_field will generate names attributes in the format:
messages[subject]
Consequently, your params will be in the format:
params[:messages][:subject]
You can also use <%= debug params %> to inspect what's in params, it's very helpful.
You can get parameter value using datas = params[:messages]
These values are in array form. So you can fetch array datas If you want to individual data then usesubject = datas[:subject]
body = datas[:body]
To check run following code in view
<%= subject %>
this gives the value of subject.

Moving this action that works in the show view into the index view (Rails)?

This is how the user votes the current post that it is showing:
controllers/votes_controller.rb:
class VotesController < ApplicationController
def vote_up
#post = Post.find(params[:id])
if #post.votes.exists?(:user_id => current_user.id)
#notice = 'You already voted'
else
#vote = #post.votes.create(:user_id => current_user.id, :polarity => 1)
end
respond_to do |format|
format.js
end
end
This updates the total number of votes with Ajax:
vote_up.js.erb:
<% unless #notice.blank? %>
alert("<%= #notice %>");
<% end %>
<% unless #vote.blank? %>
$('.post-<%=#post.id%> span.vote-count').html('<%= #post.votes.count %>');
$('.post-<%=#post.id%> div.voted-user').html('<% #post.votes.each do |vote| %><%= link_to vote.user.username, vote.user %><% end %>');
<% end %>
This is the voting link in the show view:
views/posts/show.html.erb:
<%= link_to "Vote Up", vote_up_path(#post), :remote => true, :class => "vote-up" %><br />
and the routing for the action:
routes.rb:
get 'votes/:id/vote_up' => 'votes#vote_up', as: 'vote_up'
This is how all the posts are displayed in the index view:
views/posts/index.html.erb:
<% #posts.each do |post| %>
<h2>Title: <%= post.title %></h2>
<p>Author: <%= post.user.username %></p>
<p>Created At: <%= post.created_at %></p>
<p>Content: <%= post.content %></p>
<p>Votes: <%= post.total_votes %></p>
<p>Comments: <%= post.comments_count %></p>
<ul>
<li><%= link_to 'Show', post %></li>
<li><%= link_to 'Edit', edit_post_path(post) %></li>
<li><%= link_to 'Destroy', post, confirm: 'Are you sure?', method: :delete %></li>
</ul>
<br />
<% end %>
I would like to add the voting link in the index.html.erb view for each post or find a way of triggering the vote_up action for each post in the index view. Any suggestions to accomplish that?
I think I must be totally missing the point here but why can't you just do the following within the block displaying each post?
<%= link_to "Vote Up", vote_up_path(post), :remote => true, :class => "vote-up" %>
Note that i'm using post not #post.

ActiveResource, a model, and Form_Tag

I am trying to use form_tag to pass the params captured by the form to my users controller. I am attempting to communicate with a Sinatra server, and so I do not have a database on the client. My view is as follows:
<% form_tag(#user) do %>
<div class="field">
<%= label_tag :first_mame %><br />
<%= text_field_tag :first_name %>
</div>
<div class="field">
<%= label_tag :last_name %><br />
<%= text_field_tag :last_name %>
</div>
<div class="field">
<%= label_tag :email %><br />
<%= text_field_tag "user[email]" %>
</div>
<div class="field">
<%= label_tag :device_id %><br />
<%= text_field_tag "user[device_id]" %>
</div>
<div class="field">
<%= label_tag :type %><br />
<%= text_field_tag "user[device_type]" %>
</div>
<div class="actions">
<%= submit_tag %>
</div>
<% end %>
The create action on my controller is simply:
def create
#user = User.new(params[#user])
#user.save
respond_to do |format|
if #user.save
format.html { redirect_to(#user, :notice => 'User was successfully created.') }
format.json {render :json => #user }
format.xml { render :xml => #user, :status => :created, :location => #user }
else
format.html { render :action => "new" }
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
end
end
end
Here's what I get as a result => expected an attributes Hash, got nil
Anybody know why? Thanks for the help.
You need to use form_for and not form_tag. form_for(#user) do
In your model you need to create a schema. Without it Rails doesn't know what do with the data you enter into the form.
When you pass the object into the parameter hash use :user and not #user. #user = User.new(params[:user])
For your form you need to do
<%= form_for #user do |f| %>
<div class="field">
<%= f.label :first_name %>
<%= f.text_field :first_name %>
</div>
# more fields
<% end %>
Note the:
<% %> --> <%= %>
form_tag(#user) do --> form_for(#user) do |f|
label_tag --> f.label
text_field_tag --> f.text_field
In you controller:
#user = User.new(params[:user])
Update:
<% %> --> <%= %>: This is just the convention in rails3, when ever you want to write something in the response you should use later(with = sign). Earlier still works but is deprecated.
form_tag(#user) do --> form_for(#user) do |f|
form_tag(#user) do: form_tag is used to for simple forms which are not tied with any model. You can have the tags inside form_tag named so that they resemble form for, but then why wouldn't you use form_for directly. Apparently the first parameter to the helper is target url, and in this particular case rails magically identifies the url from #user and you didn't notice any bug
form_for(#user) do |f|: form_for is used to create a form for a model, and ties up the form with the instance of the model passed to it. The block for form_for receives a form_builder object, which has equivalents of text_field_tag, label_tag etc. as text_field, label
label_tag --> f.label: first is the common tag which just creates a label tag with no magic attached to it.The later is related with the model object and follows different naming and id conventions, than former. It also ties up with the value of the field, i.e. if the field has an error(failed validation), your label will be surrounded by a div tag with class fields_with_error or something, I can't remember the class name.
text_field_tag --> f.text_field: Former will create a field with name first_name with no magic attached. The later follows a naming convention, the input field will be named user[first_name], so that when you do params[:user] you get a first_name parameter there. It also ties up with the value of the field with the html input, i.e. you get the same error functionality as label and you also get the input automatically prefilled with whatever the value field has in the model instance.