I am new in Rails. And I have a project that;
I should get a value from user in View page (for example index), and I should use the value in Helper then send the result of Helper to Controller and show the result in a new View page (for example details). Additionally I have to save results to database. Right now I have helper, controller and view pages but I can't connect these three part to each other. I need help
Controller;
def index
#user = Mpeople.new[:user]
redirect_to "secondstep"
end
def secondstep
# helper should have controled here
redirect_to "following"
end
def following
#user = Mpeople.all
end
Model;
class Mpeople < ActiveRecord::Base
has_one :username
accepts_nested_attributes_for :username
end
View;
<% form_for :user, :url => {:action => "index"} do |pform| %>
<% pform.fields_for :person do |namefield| %>
Twitter Name : <%= namefield.text_field :username %>
<%= button_to "OK", :action => "following" %>
<% end %>
<% end %>
And helper is more longer, it sends twitter name to twitter and get following of a user from api.twitter.com
This is some of my helper; I edit it after your comment but I am not sure if it is correct or not.
module FafHelper
class PeopleController
require 'people_helper'
# txtname = indexteki textbox'un adına eşitle
#txtname = tname
txtname = namefiled.text_field
.....
a_get("1/users/lookup.#{json}").
with(:query => {:screen_name => txtname, :user_id => id_list}).
end
end
..
You no need to connect views and helper as by default all the helper modules are included in the views.
And do include the helper in you controller. Helper is a module and controller is a class. Just include the module in the class.
To get the clear picture please post exactly your structure.
Related
I'm trying to make a form that will post to a database, I'm really struggling at the moment and i'm getting this error.
NameError in AddController#index
uninitialized constant AddController::Newevents
Could you advise what i would need to do?
Heres all the code i have
Form
<%= simple_form_for(#newevent) do |f| %>
<%= f.input :eventname, required: true %>
<%= f.input :eventdate %>
<%= f.input :eventimage %>
<%= f.button :submit %>
<% end %>
controller
class AddController < ApplicationController
def index
#newevent = Newevent.new
end
end
Model
class Newevent < ActiveRecord::Base
def event_params
params.require(:Newevent).permit(:eventname, :eventdate, :eventimage)
end
end
Routes
resources :add
Edit
i now have this error undefined methodnewevents_path'` after changing this
#newevents = Newevent.new
It seems that you miscopied your code here. The error message indicates that your index method actually looks like this
def index
#newevent = Newevents.new
end
Remove the s from the end of Newevent and it should work.
RE: your edit
Your routes declare that you have a resource named add, if you want to show and create your Newevent objects, then you should create a controller for that. Declare resources :newevents in your routes and create a controller to handle it.
You should research RESTful routes, because that's what Rails's resource routing works best with. The form to create a new object should be displayed by the new action and not index.
You should be using create method instead of index if you are using POST http method. index will be called if you are using GET method and it shouldn't be used to post the form data. Refer this link for more information on rails routing.
class AddController < ApplicationController
def create
#newevent = Newevent.new
end
end
I'm trying to make simple app. I input my first name and last name to simple <%= form_for #data do |f| %> rails form and after submitting it, app should render simple text like this. My first name is <%= data.first_name %> and my last name is <%= data.last_name %>. I don't know why but my app is saying this error:
undefined local variable or method `data' for
It's probably saying it because no params are passed to view.
Here is my code.
routes.rb
resources :data, only: [:new, :create, :index]
data_controller.rb
class DataController < ApplicationController
def new
#data = Data.new
end
def index
end
def create
#data = Data.new(data_params)
if #data.valid?
redirect_to #data
else
render :new
end
end
private
def data_params
params.require(:data).permit(:first_name, :second_name)
end
end
/views/data/new.html.erb
<%= form_for #data do |f| %>
<%= f.label :first_name %>
<%= f.text_field :first_name %>
<%= f.label :second_name %>
<%= f.text_field :second_name %>
<%= f.submit 'Continue', class: 'button' %>
<% end %>
/views/data/index.html.erb
<h2>Coolest app ever :D</h2>
<p>My first name is: <%= data.first_name %>.</p>
<p>And my second name is: <%= data.second_name %>.</p>
/models/data.rb
class Data
include ActiveModel::Model
attr_accessor :first_name, :second_name
validates :first_name, :second_name, presence: true
end
Please help to find out why params are not passing to next page. Thanks anyways :D
Your view should look like this:
<h2>Coolest app ever :D</h2>
<p>My first name is: <%= #data.first_name %>.</p>
<p>And my second name is: <%= #data.second_name %>.</p>
Also, I would suggest that calling a model something generic like Data is not a very Rails-y approach. Generally, domain models correspond to real-world things like User and Article, which are easy to understand and relate to. It'll get confusing quite fast if you use need to make another model and want to call it Data2 or something :)
Edit:
Since you specified that you do not wish to use the database, I would recommend passing in the object params through the redirect:
redirect_to(data_path(data: #data))
and in your controller's index method:
def index
#data = Data.new(params[:data])
end
Now your view should render properly, since you're passing the in-memory #data object attributes as params within the redirect. You then recreate this object in the index page or wherever you wish to redirect to.
To expand on Matt's answer, the reason you're getting NilClass errors is because:
You're redirecting to a data#show action when no show action has been enabled within your routes file. Since you've set your views up for the index, I'm assuming you want to redirect there when the #data object has been verified as valid:
redirect_to data_path
However I would recommend you follow Rails conventions and specify the data#show route within your routes.rb:
resources :data, only: [:index, :new, :create, :show]
and in your data_controller.rb:
def show
#data = Data.find(params[:id])
end
Another problem is that you're not actually saving the #data object upon creating it. The new method populates the attributes, and valid? runs all the validations within the specified context of your defined model and returns true if no errors are found, false otherwise. You want to do something like:
def create
#data = Data.new(data_params)
if #data.save
redirect_to data_path
else
render :new
end
end
Using save attempts to save the record to the database, and runs a validation check anyways - if validation fails the save command will return false, the record will not be saved, and the new template will be re-rendered. If it is saved properly, the controller will redirect to the index page, where you can call upon the particular data object you want and display it within your view.
I have an object that I am trying to allow users to edit in my rails 4 app. The user has_one supp_form and I want them to be able to edit the information in the supp_form. The page is loading fine and the relationships are setup properly.
The error
No route matches [PATCH] "/businesses/3/supp_form/edit"
when I rake routes I see the following route:
edit_business_supp_form_path GET /businesses/:business_id/supp_form/edit(.:format) supp_forms#edit
GET /businesses/:business_id/supp_form(.:format) supp_forms#show
PATCH /businesses/:business_id/supp_form(.:format) supp_forms#update
PUT /businesses/:business_id/supp_form(.:format) supp_forms#update
supp_forms_controller.rb
class SuppFormsController < ApplicationController
before_filter :authenticate_user!
def new
#suppform = SuppForm.new(supp_form_params)
end
def create
#suppform = SuppForm.create(supp_form_params)
end
def edit
#user = User.current_user
#suppform = #user.supp_form
end
def update
#user = current_user
#suppform = SuppForm.update(supp_form_params)
end
private
def supp_form_params
params.require(:supp_form).permit(:id, :business_id, :title, :first_name,
:last_name, :applicant_role, :work_phone_number)
end
end
View
<%= form_for #user.supp_form, :url => edit_business_supp_form_path(#user.supp_form), :html => { :class => "sky-form", :id => "sky-form4" } do |supp_form| %>
<%= supp_form.text_field :work_phone_number, :placeholder => "Your new phone number" %>
<% end %>
The problem is that it tries to access the route using a PATCH request, that is used for updating. In your routes the /businesses/:business_id/supp_form/edit route is only specified for GET requests, thus the error.
This happens because the path you are using in the form points to the edit action (which is only responsible for showing the edit form) and should instead point to the update action. So the route you should be actually using in the is the supp_form_path that, in connection with the PATCH method, pushes the information to the update action, where the object is updated.
I'm trying to get a link on an articles show page so that when a user clicks write new review it takes them to the link
/comic_reviews/'the article they want to comment on'/reviews/new
where they will be directed to the new reviews page
how can i accomplish this with
In your routes file you would specify a route like this
match '/comic_reviews/:comic_name/reviews/new' => 'reviews#new', via: :get
Then in your reviews controller you would need something like this
reviews_controller.rb
class ReviewsController < ApplicationController
def new
#comic = Commic.find_by_name(params[:comic_name])
if #comic
#review = #comic.reviews.build
render 'new'
else
#Render some error page since comic was not found
end
end
end
You will then have access to #comic and #review in your reviews/new view so you could build a form that just makes a post to create a review and allows you to store it. This should get you going.
Edit
In your new view you'd need to have a form that looks something like this
<%= form_for #review do |f| %>
<%= f.label :some_attribute %>:
<%= f.text_field :some_attribute %><br />
<%= f.submit %>
<% end %>
This will be expecting you have a route to create a review in your routes file and an action in your ReviewsController.
If you are struggling with such topics I suggest you read over this excellent tutorial
http://ruby.railstutorial.org/ruby-on-rails-tutorial-book
Or just read through the documentation for Rails API which will give you pretty accurate examples.
You can do this via routes
resources :comic_reviews do
resources :reviews
#probably_some_other_route_here
end
And with restful pattern it will be easy to achieve whatever you want
controller
Someclass < Someotherclass
#some your code
def new
#instance_var = Your_model.new
end
def create
#instance_var = Your_model.new(params[:some_name_here])
if #instance_var.save
redirect_to somewhere
else
render 'new'
end
end
end
Also you'll need form, but i dont think that will cause any troubles
I'm building a multi-step form in rails. It's not javascript driven, so each page has its own controller action like "step1" "step2" etc. I know how to do multi-step wizards through JQuery but I don't know how to keep rails validations per page without getting into javascript, hence this way.
Anyways, my model is a User object but I'm storing all my variables in an arbitrary Newuser variable and using the following in the view:
<% form_for :newuser, :url => { :action => "step3" } do |u| %>
In the controller, I merge the current page's info with the overall hash using:
session[:newuser].merge!(params[:newuser])
This works great except that if the user clicks back to a previous page, the fields are no longer populated. How do I keep them populated? Do I need to change the object in the form_for to somehow refer to the session[:newuser] hash?
EDIT:
I guess I'm looking for more info on how form_for autopopulates fields within the form. If it's not built around a model but an arbitrary hash (in this case, session[:newuser]), how do I get it to autopopulate?
This is how we did a multi-step form with validations
class User < ActiveRecord::Base
attr_writer :setup_step
with options :if => :is_step_one? do |o|
o.validates_presence_of :name
end
with options :if => :is_step_two? do |o|
o.validates_presence_of :email
end
def setup_step
#setup_step || 1
end
def is_step_one?
setup_step == 1
end
def is_step_two?
setup_step == 2
end
def last_step?
is_step_two? #change this to what your last step is
end
end
Then in the controller:
UsersController
SETUP_STEPS{1 => 'new', 2 => 'step_two'}
def new
#user = User.new
end
def step_two
end
def create
#user = User.new(params[:user])
if !#user.valid?
render :action => SETUP_STEPS[#user.setup_step]
elsif #user.last_step?
#user.save
#do stuff
else
render :action => SETUP_STEPS[#user.setup_step]
end
end
end
And then in your forms, they are like like any other rails form with one exception, you will need a hidden field to hold the values from your previous steps.
- form_for #user, :url => users_path do |f|
- [:login, :password].each do field
= f.hidden_field field
What about still using a class for your population?
class User
attr_accessor :credit_card, :name, :likes_fried_chicken
def initialize(options = {})
options.each do |key, value|
self.send("#{key}=", value)
end
end
end
you could use some tableless model functions here if you wanted to include some validations.
Then in your controller steps:
def step_one
#user = User.new(session[:new_user])
end
your forms should continue to work.
Another option is just to set the value of the form objects directly from your session hash
- form_for :user, :url => step_2_path do |f|
= f.text_field :name, :value => session[:new_user][:name]