Undefined method which is not used - ruby-on-rails

Hello i'm new one in ruby on rails. I have strange problem. I use some tutorial and get error which i shouldn't get.
I have controller
class DiaryController < ApplicationController
before_action :authenticate_user!
respond_to :html, :xml, :json
respond_to :js, :only => [:create, :update, :destroy]
def create
#record = Record.create(record_params)
#record.userId=current_user.id
if request.xhr? || remotipart_submitted?
sleep 1 if params[:pause]
render :layout => false, :template => (params[:template] == 'escape' ? 'comments/escape_test' : 'diary/create'), :status => (#record.errors.any? ? :unprocessable_entity : :ok)
else
redirect_to diary_path
end
end
def add
#record = Record.new
#respond_with(#record, :layout => false)
respond_with do |format|
format.html { render :layout => ! request.xhr? }
end
end
# PUT /comments/1
# PUT /comments/1.xml
def update
#record = Record.find(params[:id])
respond_with do |format|
format.html{ redirect_to #record }
end
end
def delete
#comment = Comment.destroy(params[:id])
end
def edit
#record = Record.find(params[:id])
end
def index
#records = Record.where(userId: current_user.id)
end
private
def record_params
params.require(:record).permit(:photo, :comment, :date, :photo_cache)
end
end
Have view
<h1 align="centre">
Добавить запись
</h1>
<%= render 'form' %>
<%= link_to 'Отмена', diary_path, :id => 'cancel-button' %>
and
<%= form_for(#record, :remote => (params[:action] == 'add' ? true : false)) do |f| %>
<fieldset>
<div class="field">
<%= f.label :date, :class => 'required' %><br />
<%= f.date_select :date %>
</div>
<div class="field">
<%= f.label :comment %><br />
<%= f.text_area :comment %>
</div>
<div class="field">
<%= image_tag(#record.photo_url(:thumb)) if #record.photo? %><br />
<%= f.label :photo %><br/>
<%= f.file_field :photo %><br/>
<%= f.hidden_field :photo_cache %>
</div>
</fieldset>
<table>
<tr>
<td>
<div class="actions">
<%= f.submit "Добавить", :data => {:'disable-with' => "Submitting..."} %>
</div>
</td>
<td>
<%= link_to 'Отмена', diary_path, :id => 'cancel-button' %>
</td>
</tr>
</table>
And get ActionView::Template::Error (undefined method `records_path' for #<#:0x000000054461c8>): error on "<%= form_for(#record, :remote => (params[:action] == 'add' ? true : false)) do |f| %>" line. Even records_path i did'n use.
I Have routes
devise_for :users
get 'welcome/index'
root 'welcome#index'
get 'diary' => 'diary#index'
get 'diary/add_record', to: 'diary#add', as: 'add_record'
post 'diary/add_record', to: 'diary#create'
get 'diary/edit_record/:id', to: 'diary#edit'
delete 'diary/edit_record/:id' => 'diary#delete
And and try to use add_record route. Maybe it would be better to use resources :records.But i want to figure out why my routes doesn't work.
view name "diary".

Because you're new to RoR, let me explain why you're receiving the error
form_for
form_for is the likely reason why you're receiving this error (oh, I just saw it actually states this is where the error occurs - sweet)
The problem you have is that form_for is meant as a way to render a form around an ActiveRecord object. It's mean to give some semi-persistence to the data, by using AR in both the new and create actions (allowing you to show the in-putted data on the form after submission)
When you pass an object to form_for, Rails automatically "builds" the form from the ActiveRecord object, one of the options it uses being the url
--
Routes
The problem you have is the object you pass to the form_for takes the model_name attribute to build the route. This means if you want to use the form_for method by just passing an object, it's going to look for routes pertaining directly to that object
If you don't have any [model]_path route set up, you'll likely receive the error you're getting. The fix firstly involves the routes, and secondly involves the controller:
#config/routes.rb
root 'welcome#index'
devise_for :users
resources :diary, path_names: { new: "add_record", create: "add_record", edit: "edit_record", destroy: "edit_record" }
resources :welcome, only: :index
This is down to the idea that Rails' routing structure is built around resources - every route you have should lead to a specific controller action. Whilst including custom actions is completely fine, you have to appreciate that the basis of the routing structure is to construct resourceful routing, which essentially means that Rails perceives every controller / model to have corresponding routes:
--
URL
The second thing to observe is the url of the form
If you have your routes set up as above, and if your routing structure differs from your model structure (different names), you'll want to use the following setup to define the url explicitly:
<%= form_for #record, url: your_custom_path do |f| %>

Related

Rails form rendering wrong URL after validation errors (not keeping passed parameter)

On a project show page, I pass a very simple parameter on my 'create new task' that stores which project its from:
#project.id), :class => "btn btn-info col-md-12" %>
so that when i create a new task for it, it stores it in the URL on my new task form like this:
http://localhost:3000/task/new?project_id=5
My New form is as follows:
<div class="container sign-in-register">
<div class="authform">
<%= form_for #task, :html => {:multipart => true} do |f| %>
<h3>Add a task for this project...</h3><br/>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= hidden_field_tag 'project_id', #project_id %>
<%= f.fields_for :taskrelationships do |ff| %>
<%= ff.hidden_field :taskproject_id, value: #project_id %>
<%= ff.label :task_url %>
<%= ff.text_field :task_url, class: 'form-control' %>
<% end %>
<br clear="all">
<%= f.submit "Save Task", class: "btn btn btn-info" %>
<% end %>
</div>
</div>
As you can see i'm using nested attributes in the form (I am creating both a task and a TaskRelationship. Now, when I try to save without filling out all the required fields a validation is thrown but for some reason it redirects me to:
http://localhost:3000/tasks
instead of the original:
http://localhost:3000/tasks/new?project_id=5
I have read many posts and none seem to answer this particular case. The stackO post below was close but when I try it with task instead of user it still cannot find the task_ID
Render error on new page with customize url like http://localhost:3000/education_informations/new?user_id=10
How can I have rails simply render the same exact url as I started with - it seems like this should be easy so must be missing something small.
My controller actions:
def new
#project_id = params[:project_id]
#task = Task.new
#task.taskrelationships.build
end
def create
#project = Project.find(params[:project_id])
#task = Task.new(task_params)
if #task.save
flash[:success] = "This task has been added."
#task.taskrelationships.create!(#taskrelationships_params)
redirect_to tasks_project_path(#project)
else
#task.taskrelationships.build(#taskrelationships_params)
flash[:alert] = #task.errors.full_messages.to_sentence
render :new
end
end
private
def task_params
#taskrelationships_params = params.require(:task).permit(taskrelationships_attributes: [
:task_url,
:taskproject_id
])[:taskrelationships_attributes]["0"]
params[:task].delete(:taskrelationships_attributes)
params.require(:task).permit(
:name,
:user_id,
taskrelationships_attributes: [
:task_url,
:taskproject_id
]
).merge(owner: current_user)
end
UPDATE W / ROUTES
resources :projects do
resources :reviews, except: [:destroy]
member do
get :tasks
end
end
resources :tasks
resources :taskrelationships, only: [:create, :destroy] do
post :vote, on: :member, controller: "task_relationships"
end
thanks for any assistance...
Ok firstly an explanation as to what is going on here:
When you invoke http://localhost:3000/task/new?project_id=5 you are actually being routed to the new action on the task controller (with a project_id param).
Your new action then sets the variables and rails will render the new.html.erb which contains your new task form.
When you submit the form it actually is doing a http POST to /tasks, which routes to the create action of your tasks controller. That url and http method is a result of what is generated from the form_for helper:
<%= form_for #task, :html => {:multipart => true} do |f| %>
This is why the url changes from /tasks/new?project_id=5 to /tasks
Now the create action if it fails the validation simply renders the new form - it is not redirecting anywhere - the url remains unchanged from what it was when it entered this action - meaning, it remains as /tasks.
You do not actually need to navigate to /tasks/new?project_id=5 to render the new form but what you do need to do is set #project_id in the controller so the view has access to that variable (just as it does in the new action):
def create
#project = Project.find(params[:project_id])
#task = Task.new(task_params)
if #task.save
flash[:success] = "This task has been added."
#task.taskrelationships.create!(#taskrelationships_params)
redirect_to tasks_project_path(#project)
else
#task.taskrelationships.build(#taskrelationships_params)
#project_id = #project.id
flash[:alert] = #task.errors.full_messages.to_sentence
render :new
end
end
So, to clarify the change in url is not a redirection it's just that the form is posting to a different url than /tasks/new, and this is actually just a cosmetic issue.
Now if it is a concern to you, you can change the routing to something like the following:
resources :tasks, except: [:create, :new]
post 'new_task' => 'tasks#create'
get 'new_task' => 'tasks#new'
This is mapping the POST and GET http methods to /new_task so the url appears the same for the new and create action invocations. Note you do need to change the url in the form_for helper to use this new route:
<%= form_for #task, url: 'new_task', multipart: true do |f| %>
Since Rails default behaviour in forms is with remote: true, you can move the content of the form to a partial(let's name it _my_form.html.erb), add to the controller action (let's say in create action):
respond_to do |format|
format.js {}
end
Then add a create.js.erb file where you will render the form partial
$("#form").html(
"<%= j render partial: 'my_form', locals: { entity: #entity } %>"
);
Thus, validation errors and all attributes will be accessible inside the form and there is no need to hack the "Rails approach"
I had to adapt and experiment with the currently accepted answer,
and the following ended up working well (using schools rather than tasks):
In config/routes.rb:
resources :schools do
...
end
post 'schools/new' => 'schools#create'
And create the form like:
= simple_form_for [#school], url: 'new' do |f|
Thus the path /schools/new was preserved on validation :)

Want to edit/PUT/PATCH but error says "No route matches [POST]"

I'm building my second-ever basic Ruby on Rails application and having fun doing it, but have gotten stuck at precisely the same place that gave me trouble (and was never solved) on my last effort: the PUT or PATCH request.
My application has two models: entries and users. A logged-in user should be able to edit only those entries that were originally created by that user.
CONTROLLER
class EntriesController < ApplicationController
# authenticate user (Devise)
before_action :authenticate_user!, :except => [:index, :show]
# set entry upon page load
before_action :set_entry, :only => [:show, :edit, :update, :destroy]
# GET request - display all entries
def index
#all_entries = Entry.all
end
# GET request - display an individual entry
def show
# nothing required here because entry identified with before_action :set_entry on line 2 above
end
# GET request - access form to create a new entry
def new
#entry = Entry.new
#user = User.find(current_user[:id])
end
# GET request - access form to update an existing entry
def edit
if #entry[:user_id] != current_user[:id]
redirect_to root_path
else
redirect_to edit_entry_path
end
end
# POST request - make a new entry/save new data into db
def create
user = current_user[:id]
Entry.create({
entry_title: params[:entry][:entry_title],
book_title: params[:entry][:book_title],
text: params[:entry][:text],
img_url: params[:entry][:img_url],
tag: params[:entry][:tag],
created_at: params[:entry][:created_at],
user_id: user
})
redirect_to entries_path
end
# PUT request - save changes to an existing entry
def update
if #entry.update(entry_params)
redirect_to entry_path
else
render :new
end
end
# DELETE request - delete an existing entry from db
def destroy
#entry.destroy
redirect_to entries_path
end
private
def set_entry
#entry = Entry.find(params[:id])
end
def entry_params
params.require(:entry).permit(:email, :text, :tag)
end
end
VIEW (show.html.erb - shows a single entry and includes links allowing the logged-in user who originally authored the entry to edit or delete it)
<h3>Selected Entry</h3>
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-6">
<div>Entry title: <%= #entry.entry_title %></div>
<div>Book title: <%= #entry.book_title %></div>
<div>Text: <%= #entry.text %></div>
</div>
<div class="col-md-4">
<div><%= #entry.created_at.strftime("%b %d, %Y") %></div>
<div>Submitted by: <i><%= #entry.user.email %></i></div>
<div>File under: <i><%= #entry.tag %></i></div>
<% if current_user %>
<%= link_to 'Edit', #entry, :method => 'update' %>
<%= link_to 'Delete', #entry, :method => 'delete' %>
<% end %>
</div>
</div>
ROUTES.RB - At first my routes were the commented-out lines, but then I had a thought that was either madness or sudden realization - should only the GET routes lead with "get"? So that's the non-commented-out attempt you see. Somehow the app works (except for the issue at hand) both ways.
In researching I've come across routes defined using a much more elaborate syntax than that I'm using here. I've been unable to figure out whether a given way of doing things is different convention, outdated, or just inadequate to the task.
Rails.application.routes.draw do
devise_for :users
resources :entries
# root 'entries#index'
# get '/entries' => 'entries#index'
# get '/users' => 'users#index'
# get '/entries/:id' => 'entries#show'
# get '/entries/:id' => 'entries#update'
# get '/entries/new' => 'entries#new'
# get '/entries/:id/edit' => 'entries#edit'
# get '/users/:id' => 'users#show'
# get '/about' => 'pages#index'
root 'entries#index'
get '/entries' => 'entries#index'
get '/entries/new' => 'entries#new'
post '/entries' => 'entries#create'
get '/entries/:id' => 'entries#show'
get '/entries/:id/edit' => 'entries#edit'
put '/entries/:id' => 'entries#update'
delete '/entries/:id' => 'entries#destroy'
get '/users' => 'users#index'
get '/users/:id' => 'users#show'
get '/about' => 'pages#index'
end
Thanks in advance for any insight. If additional context is needed I'm happy to provide.
Edited to add:
PARTIAL (_form.html.erb)
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-6" id="form-container">
<%= form_for #entry do |form| %>
<br>
<%= form.text_field :entry_title, :size => 59, :placeholder => "Entry Title"%>
<br><br>
<%= form.text_field :book_title, :size => 59, :placeholder => "Book Title"%>
<br><br>
<%= form.text_field :img_url, :size => 59, :placeholder => "Image URL"%>
<br><br>
<%= form.text_area :text, :placeholder => "Text" %>
<br><br>
<%= form.text_field :tag, :placeholder => "Tag" %>
<br><br>
<%= form.submit %>
<% end %>
</div>
<div class="col-md-4"></div>
</div>
To edit a record you
first, should use a GET request to get the edit form
second, should submit that form using a PUT/PATCH request
To get to the edit form you should link to the edit path for your entry
<%= link_to 'Edit', edit_entry_path(#entry) %>
The Rails form helpers will automatically set the form to submit with the proper method, PUT OR PATCH.
:method in link_to helpers refers to HTML verb (get, post, etc), while controllers methods naming convention is action.
link_to
You need something as
<%= link_to 'Edit', #entry, :method => 'put' %>
or
<%= link_to 'Edit', #entry, :action => 'update' %>
At a glance you are trying to post with the edit link. Remember new/edit are get methods to render form, so just just delete method part in your links. Like from
<%= link_to 'Edit', #entry, :method => 'update' %>
to
<%= link_to 'Edit', edit_entry_path(#entry) %>
I'm building my second-ever basic Ruby on Rails application
Congrats! You need at least 3 more before it all starts to make sense
To add to the existing answers, you'll be best looking at the resources directive to clean the routes up:
#config/routes.rb
root 'entries#index'
devise_for :users
resources :entries
resources :pages, only: [:index], path_names: { index: "about" }
resources :users, only: [:index,:show]
--
A logged-in user should be able to edit only those entries that were originally created by that user.
This is known as authorization.
Authentication = is user logged in?
Authorization = can user do this?
Although people confuse Devise with being able to handle authorization, it only handles authentication. Whilst you have a simple implementation of this in your controller, you should check out either the CanCanCan or Pundit gems:
#Gemfile
gem "cancancan"
#app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
can :manage, Post, user_id: user.id
end
end
#app/controllers/entries_controller.rb
class EntriesController < ApplicationController
def edit
authorize! :edit, #entry
end
end
--
Finally, to answer your question directly, you're calling the update method (which doesn't exist) to access the edit view:
<% if current_user %>
<%= link_to 'Edit', #entry, :method => 'update' %>
<%= link_to 'Delete', #entry, :method => 'delete' %>
<% end %>
You should read up about http verbs - this is what the "method" option invokes with the link. As mentioned above, you don't need to set the method for edit as it uses GET. Update uses put/patch, which I can explain later.
A much better way to achieve what you want would be the following:
<%= link_to "Edit", edit_entry_path(#entry) if can? :edit, #entry %>
<%= link_to "Delete", #entry, method: :delete, if can? :destroy, #entry %>
The above uses the CanCanCan authorization method can?

Couldn't find Timetable with 'id'=clas

Generated a timetable scaffold. Then later created a new action "clas" in my timetables_controller.rb.
timetables_controller.rb
class TimetablesController < ApplicationController
before_action :set_timetable, only: [:show, :edit, :update, :destroy, :clas]
def clas
#classtimetable = Timetable.where(params[:clas])
end
//other actions
def set_timetable
#timetable = Timetable.find(params[:id])
end
def timetable_params
params.require(:timetable).permit(:day, :clas, :one_teacher, :one_sub, :two_teacher, :two_sub, :three_teacher, :three_sub, :four_teacher, :four_sub, :five_teacher, :five_sub, :six_teacher, :six_sub, :seven_teacher, :seven_sub, :eight_teacher, :eight_sub)
end
end
Created form_for to the action "clas". Need to pass the select option values as params to the controller
clas.html.erb
<% form_for #classtimetable, :url => clas_timetables_path, :html => { :method => :post} do |f| %>
<div class="field">
<%= f.label "Select class" %>
<% values = ["1c", "2c", "3c", "4d", "5i"] %>
<%= f.select :clas, options_for_select(values) %>
</div>
<div class="actions">
<%= f.submit "Submit"%>
</div>
<% end %>
<% #classtimetable.each do |class_timetable| %>
<%= class_timetable.day %>
<% end %>
routes.rb
resources :timetables do
member do
get 'clas'
end
end
I need to get all the day for the class in my clas.html.erb page. Which is done by selecting the class from dropdown and submit. The value should be passed in params when i click submit.
don't know how to fix it. Any ideas?
Add controller in form_for tag,
<% form_for #classtimetable, :url => { :controller => "your-controller-name", :action => :clas } do |f| %>
Or you can directly write like this,
<% form_for #classtimetable, :url => clas_timetables_path, :html => { :method => :post} do |f| %>
Change before_action like,
before_action :set_timetable, only: [:show, :edit, :update, :destroy, :clas]
You would change collection to member and pass id
resources :timetables do
member do
get 'clas'
end
end
Try to change your form_tag like this,
<% form_for #classtimetable, :url => clas_timetables_path(#classtimetable), :method => :post do |f| %>
Can you try this
def clas
#classtimetable = Timetable.where(timetable_params[:clas]).first
end
First I recognized: You used get in routes, and post in form. So the actions won't match.
Second: You've written:
still getting the same error undefined method `model_name' for Timetable::ActiveRecord_Relation:Class
So look, how you defined #classtimetable
#classtimetable = Timetable.where(params[:clas])
This is a relation, not the ActiveRecord, you want to find by clas. The error will be thrown on this line:
<% form_for #classtimetable, :url => clas_timetables_path, :html => { :method => :post} do |f| %>
form_for expects as first argument an ActiveRecord or something similar (at least something extending ActiveModel::Naming). Since I do not see your definition of Timetable, I just guess, it has an attribute called clas and you want to find the Timetable with clas equals the selection in that form. So it would be:
#classtimetable = Timetable.find_by(clas: params[:clas])
what is the same as:
#classtimetable = Timetable.where(clas: params[:clas]).first
To get the first element from that Relation, you tried to use.
Third: Since you did define your route to be a member route, it should expect an id in clas_timetable_path. Since you load #timetable in clas action in before_filter, I think you want to have there:
<% form_for #classtimetable, :url => clas_timetables_path(#timetable), :html => { :method => :get} do |f| %>

Rails accessing custom method instance variable

What I am trying to do is add a simple search to a 'show' view in my rails app. I've watched the rails cast about simple search and it's given me some good direction but I can't seem to get it to work with my situation. I just have a list of FAQs and want to have a search filter for the 'question(s)'.
Here's my views/guests/show.html.erb
<%= form_tag faq_search_guests_path, method: :get, remote: true, :id => "faq_search_form" do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
<div id="faq-search-test"></div>
<% #faqs.each do |f| %>
<h4>Question</h4>
<%= f.question %>
<h4>Answer</h4>
<%= f.answer %>
<% end %>
Here's the controller/guests_controller.rb method that originally sets #faqs
def show
#guest = Guest.find(params[:id])
#hotel = Hotel.find(params[:hotel_id])
#faqs = Faq.where(hotel_id: #hotel.id)
#template = Template.where( hotel: #hotel.id )
#visit = Visit.where("hotel_id = ? AND guest_id = ?", #hotel.id, #guest.id).last
#visit = Visit.find(params[:visit_id]) if params[:visit_id] && (#visit.hotel_id == #hotel.id)
unless current_user.hotels.include?(#hotel)
render :file => "public/401.html", :status => :unauthorized
end
end
Here's my controllers/guests_controller.rb custom method my form is calling
def faq_search
#faq_result = Faq.search(params[:search])
render :nothing => true
end
Here's my routes.rb for that
resources :guests do
get 'faq_search', :on => :collection
end
resources :faqs
Here's my models/faq.rb
def self.search(search)
if search
where('question LIKE ?', '%#{search}%')
else
scoped
end
end
So from here, I am having trouble displaying #faq_result in show.html.erb. I guess I have no idea how to access an instance variable from a custom controller method from a view.
Any help would be much appreiciated :)!

Wicked gem cannot find wedding ID in update action

I'm trying to implement the 'Wicked' gem for wizards and cannot figure out this error for the life of me. Already referenced Ryan bates railscast #346 and the step by step tutorial by schneems.
I have 2 controllers: Weddings and Wedding_steps. The user initially creates a Wedding and after the create action is redirected to the Wedding_steps controller (which uses Wicked) to update the wedding model with additional info.
The wedding_id is successfully detected in the first step weddingdetails, but after submitting that step, I get the following error:
ERROR
ActiveRecord::RecordNotFound in WeddingStepsController#update
Couldn't find Wedding without an ID:
app/controllers/wedding_steps_controller.rb:11:in `update'
Parameters:
{"utf8"=>"✓",
"_method"=>"put",
"authenticity_token"=>"JMd+8gf4rVqOSNMSFrKcD3WxK+X3zvYliSMWqTg0SkE=",
"wedding"=>{"bridename"=>"",
"groomname"=>"",
"weddingdate"=>"",
"weddingcity"=>"",
"weddingstate"=>"",
"url"=>""},
"commit"=>"Next",
"id"=>"wedding_id=11"}
It is supposed to continue to the next step /wedding_steps/eventdetails?wedding_id=11 but instead gives the error and goes to /wedding_steps/wedding_id=11
Also of note is that without the Update action in place, the information successfully saves and redirects to the Wedding Show action.
Here is the relevant code:
wedding_steps_controller.rb
class WeddingStepsController < ApplicationController
include Wicked::Wizard
steps :weddingdetails, :eventdetails
def show
#wedding = Wedding.find(params[:wedding_id])
render_wizard
end
def update
#wedding = Wedding.find(params[:wedding_id])
#wedding.update_attributes(params[:wedding])
render_wizard #wedding
end
end
weddings_controller.rb
def create
#wedding = current_user.weddings.new(params[:wedding])
respond_to do |format|
if #wedding.save
format.html { redirect_to wedding_steps_path(:id => "weddingdetails", :wedding_id => #wedding.id) }
format.json { render json: #wedding, status: :created, location: #wedding }
else
format.html { render action: "new" }
format.json { render json: #wedding.errors, status: :unprocessable_entity }
end
end
end
STEP 1: wedding_steps/weddingdetails.html.erb
<%= simple_form_for(#wedding, :url => wizard_path(wedding_id: #wedding.id), :method => :put, html: { class: 'form-horizontal'}) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<div class="formrow center">
<%= f.input :bridename, placeholder: "The Bride's Name", label: false %>
<h2 class="inline"> &</h2>
<%= f.input :groomname, placeholder: "The Groom's Name", label: false %>
</div>
<div class="formrow center">
<%= f.text_field :weddingdate %>
<!-- OLD STYLE DATE FORMAT <%= f.input :weddingdate, label: "Wedding Date" %> -->
<%= f.input :weddingcity, label: "City" %>
<%= f.input :weddingstate, label: "State" %>
</div>
<div class="formrow center">
<%= f.input :url, placeholder: "i.e. 'johnandkate' ", label: false %>
</div>
</div>
<div class="form-actions center">
<%= f.button :submit, value: "Next" %>
</div>
<% end %>
<%= link_to 'skip', next_wizard_path(wedding_id: #wedding.id) %>
STEP 2: wedding_steps/eventdetails.html.erb
EVENT DETAILS STEP <!--PLACEHOLDER FOR NOW -->
Routes.rb
Jobshop::Application.routes.draw do
resources :pins
resources :weddings
resources :wedding_steps
get "users/show"
root :to => 'pages#home'
get 'about' => 'pages#about'
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
resources :inviterequests
devise_for :views
ActiveAdmin.routes(self)
devise_for :users
ActiveAdmin.routes(self)
match 'users/:id' => 'users#show'
This line:
<%= simple_form_for(#wedding, :url => wizard_path, :method => :put, html: { class: 'form-horizontal'}) do |f| %>
Should be:
<%= simple_form_for(#wedding, :url => wizard_path(wedding_id: #wedding.id), :method => :put, html: { class: 'form-horizontal'}) do |f| %>
Note the wizard_path(wedding_id: #wedding.id) When you submit the form you should see parameters = {:wedding_id => some_number} in the logs.
Paste the output of the params for the update action if it doesn't work.
Edit:
You should have ":wedding_id" as part of the required url this will make it impossible to even generate a link to that controller unless it has a properly formatted url.
Replace this
resources :wedding_steps
with this
scope "weddings/:wedding_id" do
resources :wedding_steps
end
So now a correct url would look like weddings/83/wedding_steps/weddingdetails. Likely one or more of your view helpers isn't including wedding_id properly and with this new constraint you will raise an error in the view, but this is a good thing since it will show you where the malformed link is.
I tried the solution provided by Schneems, however it is not running completely without errors. I implemented the following way.
Change
resources :wedding_steps
To
scope "weddings/:wedding_id" do
resources :wedding_steps
end
The problem is parameters are displayed as forbidden based on the error that has been thrown as ActiveModel::ForbiddenAttributesError
To get rid off this,
Change
def update
#wedding = Wedding.find(params[:wedding_id])
#wedding.update_attributes(params[:wedding])
render_wizard #wedding
end
To
def update
#wedding = Wedding.find(params[:wedding_id])
#wedding.update_attributes(wedding_params)
render_wizard #wedding
end
private
def wedding_params
params.require(:wedding).permit(........your parameters here.................)
end

Resources