Getting a No Route Match on Edit Proposals Controller - ruby-on-rails-3

This is my code in the view, just calling to the edit proposal path
<%= link_to "Edit this Proposal", edit_idea_proposal_path %>
This is my code in the Proposals Controller. I clearly have an "Edit" action, so why is it giving me a route error for Edit?
def create
#idea = Idea.find(params[:idea_id])
#proposal = #idea.proposals.create(params[:proposal])
if #proposal.save
flash[:success] = "Thanks for the Proposal!"
redirect_to idea_proposals_url(#idea)
else
render 'new'
end
end
def edit
#idea = Idea.find(params[:idea_id])
#proposal = #idea.proposals.find(params[:id])
end
def update
#idea = Idea.find(params[:idea_id])
#proposal = #idea.proposals.find(params[:id])
if #proposal.update_attributes(params[:proposal])
redirect_to idea_proposals_url(#idea)
else
render 'edit'
end
end

Figured it out, I needed to change the code in my view from:
<%= link_to "Edit this Proposal", edit_idea_proposal_path %>
To:
<%= link_to "Edit this Proposal", edit_idea_proposal_path(#idea, proposal) %>

Related

Rails: form_for in application wide footer

I started learning Rails for about a month now and I am working on a fairly simple project to improve my skills. It's a blog where editors can add articles and users can subscribe to a newsletter by adding their email. The homepage is an index view and their is a footer that shows up across all pages.
Here is my problem: I would like to include the form_for the newsletter on the footer that exists inside the application layout. That form has a specific model: Subscriber, which stores users emails.
What I've done so far is include the following on the Articles controller:
def index
#articles = Article.order(created_at: :desc).all
#subscriber = Subscriber.new
end
def create
#subscriber = Subscriber.new(subscriber_params)
if #subscriber.save
redirect_to '/home'
else
render 'new'
end
end
def subscriber_params
params.require(:subscriber).permit(:email)
end
In application.html.erb :
<%= form_for(#subscriber) do |f| %>
<%= f.email_field :email, :placeholder => "email address" %>
<%= f.submit 'Sign up', :id => "signup" %>
<% end %>
The form is displayed correctly on the index page only and it doesn't save to the database (without error).
I have tried using a before filter on the application controller as well as rendering a partial without any success.
Edit
Subscribers controller code:
def new
#subscriber = Subscriber.new
end
def create
#subscriber = Subscriber.new(subscriber_params)
if #subscriber.save
redirect_to '/home'
else
render 'new'
end
end
private
def subscriber_params
params.require(:subscriber).permit(:email)
end
Application controller:
before_action :create_new_subscriber
def create_new_subscriber
#subscriber = Subscriber.new
end

Do I need to reload the comment object or the partial that contains the comment in case of using Ajax in Rails 3?

I have been trying to figure out adding comments without reloading the page using Ajax, after reading few different tutorials this is what I came up to so far, and it's not working:
inside user_comments/_comments.html.erb
<div id="comment_form">
<%= simple_form_for [#commentable, #comment], :html => { :multipart => true }, :remote => true do |f| %>
<div class="picture"><%= image_tag current_user.avatar.url(:thumb) %></div>
<%= f.input :content, label: false, :placeholder => "Add Comment", :input_html => { :rows => 4 } %>
<%= f.submit "Add Comment" %>
<% end %>
</div>
Inside the controller:
def create
#users = User.all
#comment = #commentable.user_comments.new(params[:user_comment])
#comment.user_id = current_user[:id]
##commentable.user_comments.create(:user_id => current_user[:id])
if #comment.save
flash[:notice] = "Successfully created comment."
respond_to do |format|
format.html { redirect_to #commentable }
format.js
#format.js #{ render 'create.js.erb' }
end
else
render :new
end
end
and inside the create.js.erb
// Display a Javascript alert
<% if remotipart_submitted? %>
$("#comments_list").append("<%= escape_javascript(render(:partial => 'user_comments/comments')) %>");
<% end %>
I'm using a Gem called: remotipart
I don't know what I'm missing in the process.
in the console I get:
POST http://localhost:3000/assignments/2/user_comments
200 OK
134ms
which means the post goes through, but the comment doesnt get added back to the partial.
Ok after 2 days! I fixed it, here is what I can share and might help:
1- make sure to include the :remote => true to the form that is about to be submitted
2- Check the controller and see what the Create action is being redirected, in my case I changed to this:
def create
#users = User.all
#comment = #commentable.user_comments.new(params[:user_comment])
#comment.user_id = current_user[:id]
##commentable.user_comments.create(:user_id => current_user[:id])
if #comment.save
flash[:notice] = "Successfully created comment."
respond_to do |format|
format.html
format.js {#comments = #commentable.user_comments}
end
else
render :new
end
end
Then make sure the create.js.erb is written properly:
$("#comments_list").empty()
$("#comments_list").append("<%= escape_javascript(render(:partial => 'comments')) %>");
there you go! I hope some creates a proper tutorial for newbies like me :)!

Accessing non-current state_machine states

I've got six states on my order.rb file. I want to access each of the non-current states to populate a drop-down menu so the state can readily be changed. I've come up with this. The function doesn't work, obviously, and the states are written_like_this.
<% order.state_paths.to_states.each do |state| %>
<%= link_to(state.to_s, order.adjust(state)) %>
<% end %>
I'd like to write a catch-all method too that interprets the clicks from the above menu and transitions the record to the selected state. Something like (pseudo-code):
def adjust(state)
#order = Order.find(params[:id])
#order.state = state
end
Any thoughts would be great. Cheers!
I've figured it out.
def adjust
session[:return_to] ||= request.referer
#doc = Doc.find(params[:id])
state = params[:state]
respond_to do |format|
#doc.update_attribute(:state, state)
#doc.create_activity state.to_sym, owner: current_user
format.html { redirect_to root_url, notice: "#{#doc.title} has now been #{state}." }
format.json { render json: #doc }
end
end
And I've made the buttons like this:
<% activity.trackable.state_paths.events.each do |s| %>
<%= link_to(s.to_s.titlecase, adjust_path(s, activity.trackable)) %>
<% end %>
Boom.

Trouble with the default view undefined method `name' for nil:NilClass

I'm having trouble getting my view to render. I think I know why I'm getting the error:
undefined method `name' for nil:NilClass
Extracted source (around line #21): (showing 18-24)
<ul>
<%= form_tag(default_hero_user_path, :method=>'post') do %>
<%= label_tag "Name" %>
<%= text_field_tag "name", #user.default_hero.name %> #line 21
<%= submit_tag 'Set hero', class: "btn btn-large btn-primary" %>
<% end %>
</ul>
I know you can't call .name on a nil object but I don't understand why #user.default_hero is nil. I want the user to be able to set their 'hero' but having trouble setting the default obviously.
Here is the users controller:
# creates or updates the default hero
def default_hero
#user = User.find(params[:id])
hero = #user.default_hero
if hero.nil?
# we don't have a default hero so we need to add one'
hero = Hero.new
#user.heros << hero
end
hero.default = true
hero.name = params[:name]
hero.save
redirect_to #user # shows the user again to see any updates
end
And here is where I believe I am having the problem in setting a default view-
def show
#user = User.find(params[:id])
if #user.default_hero.nil?
name = params[:q]
else
name = #user.default_hero.name
end
Thanks for your guys' time and attention if you can point me in the right direction in how to solve this I would ppreciated.
Your show controller action doesn't make much sense. You are setting a local variable (which won't be accessible in the view) if #user.default_hero.nil?. This doesn't accomplish anything and #user.default_hero will still be nil in the view.
That being said, to get rid of your error you can simply do this:
<%= text_field_tag "name", #user.default_hero.nil? ? '' : #user.default_hero.name %>
Based on your comment I would does something like this:
Model
class User < ActiveRecord::Base
has_many :heros
def set_default_hero(name)
hero = self.heros.find_by_name(name) # check if the hero exists already
hero = self.heros.build(:name => name) if hero.nil? # new object if not
hero.default = true # set it as default
hero.save
end
end
Controller:
def default_hero
#user = User.find(params[:id])
#user.set_default_hero(params[:name])
redirect_to #user
end
def show
#user = User.find(params[:id])
#default_hero = #user.default_hero.nil? ? '' : #user.default_hero.name
end
View:
<%= text_field_tag "name", #default_hero %>
You ignored my question about params[:q], so I don't know what to do with that.

Rails Routing Redirects to wrong path

I have a view called, "clients" which shows a list of calls from the Call database. That works fine. However when I added a new button with a form behind it the call will be created but it redirects to calls_path instead of clients_path.
I have no idea why it's doing this, my only theory is that I'm working with actions that touch data outside of the clients_controller and somehow Rails is defaulting to the calls_path. The same thing happens on my delete action. Can someone help me make sense of this?
calls_controller
def new
#call = Call.new :call_status => "open"
respond_with #call
end
def create
#call = Call.new(params[:call])
if #call.save
redirect_to clients_path, notice: "Call was successfully created."
else
render :new
end
end
def destroy
#call = Call.find(params[:id])
#call.destroy
respond_to do |format|
format.html { redirect_to clients_index_path }
format.json { head :no_content }
end
end
_form.html.erb
<%= form_for(#call) do |f| %>
<%= f.label :caller_name %>
<%= f.text_field :caller_name %>
<%= f.label :caller_phone %>
<%= f.text_field :caller_phone, :placeholder => 'xxx-xxx-xxxx' %>
<%= f.label :caller_email %>
<%= f.text_field :caller_email %>
<%= f.button :submit %>
<% end %>
routes.rb
devise_for :users
match 'mdt' => 'mdt#index'
get "home/index"
resources :medics
resources :clients
resources :users
resources :units
resources :mdt do
collection do
put "in_service"
put "en_route"
put "to_hospital"
put "at_hospital"
put "on_scene"
put "out_of_service"
put "at_station"
put "staging"
put "at_post"
put "man_down"
end
end
resources :calls do
member do
post 'close'
end
end
root :to => 'home#index'
devise_scope :user do
get "/login" => "devise/sessions#new"
delete "/logout" => "devise/sessions#destroy"
end
The problem I had was with routes. I needed a post method for a new calls. After creating two actions (one for create and one for destroy) along with their routes everything started working. It looks like it was trying to use the default routes and actions which would re-route to the wrong URL for my purposes.
resources :clients do
collection do
post "calls"
end
member do
delete "cancel"
end
end
def calls
#call = Call.new(params[:call])
if #call.save
redirect_to clients_path, notice: "Call was successfully created."
else
render :new
end
end
def cancel
#call = Call.find(params[:id])
#call.destroy
respond_to do |format|
format.html { redirect_to clients_path }
format.json { head :no_content }
end
end