Work after user creation - ruby-on-rails

I create a new user with basic fields as user name and password. Then I redirect to another page where the user is allowed to complete his profile. The page looks like this.
Ok, I created the user first. Then I redirected the user to complete his profile. The profile page looks like this
<h1>User successfully created</h1>
<h3>Would you like to complete your profile now?</h3>
<%= render #profile %>
<%= render #address %>
<%= button_to 'Save',{
:controller => "users",
:action => "update",
:id => #user.id,
:profile => #profile,
:address => #address
}, :method => :put %>
The code above executes the update action in the controller. However, I am getting nil for the #profile and #address objects. I guess the button_to is having no effect on the profile and address partials.
The address partial looks as follows
<%= form_for(#address) do |f| %>
<% if #address.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#address.errors.count, "error") %> prohibited this address from being saved:</h2>
<ul>
<% #address.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<fieldset>
<legend>Addresss</legend>
<div class="field">
<%= f.label :street_address %>
<%= f.text_field :street_address, :size => 40 %>
</div>
<div class="field">
<%= f.label :street_address_2 %>
<%= f.text_field :street_address_2, :size => 40 %>
</div>
<div class="field">
<%= f.label :city %>
<%= f.text_field :city, :size => 40 %>
</div>
<div class="field">
<%= f.label :state %>
<%= f.text_field :state, :size => 40 %>
</div>
<div class="field">
<%= f.label :zip_code %>
<%= f.text_field :zip_code, :size => 40 %>
</div>
<% end %>
I would appreciate if anyone would be able to help me on this.

The button_to method only creates a button which an be used to call an controller/ go to another page.
If you want to allow the user to modify fields, you need to use a form. Please read this guide on forms for more information, especially part 2 is of interest for your situation I guess.
Edit: You need a submit button in your form to submit it, not a button_to outside the form. If you want to have both partials submitted at the same time, you need 1 big form and a controller which is able to process the data of both models.

Related

transfer IDs for a booking

I am trying to create a booking system in ruby on rails, I want a student to book an instructor. I have used devise and created separate models, instructor and student. When a student is logged in, they are able to pick their instructor which is listed, and press 'Book a lesson' both their IDs are transferred to the lesson new form.
I am having two problems, the button to transfer the chosen instructors ID and the student who is signed in ID, to the lessons new page, for the student to book a lesson time and date.
Instructor#index
<% #instructors.each do |instructor| %>
<%=instructor.id%> : <%= instructor.email %>
<%#= button_to 'Book a lesson', new_lesson_path(instructor_id: instructor) %>
<%= link_to 'Book a Lesson', {controller: :lesson, :action => :new, :instructor_id => #instructor.id} %>
<% end %>
Lessons Controller
# GET /lessons/new
def new
# #lesson = Lesson.new
#instructor = Instructor.find(params[:instructor_id])
#lesson = Lesson.new(student_id: Student.find(session[:student_id]).id)
#lesson.instructor_id = #instructor.id
end
lesson FORM new
<%= form_for(#lesson) do |f| %>
<div class="main-title"> New Lesson for "<%= #lesson.instructor.email %> "</div>
<%= f.hidden_field :instructor_id %>
<%= f.hidden_field :student_id %>
<div class="field">
<%= f.label :lesson_date %><br>
<%= f.date_select :lesson_date %>
</div>
<div class="field">
<%= f.label :lesson_start_time %><br>
<%= f.time_select :lesson_start_time %>
</div>
<div class="field">
<%= f.label :lesson_end_time %><br>
<%= f.time_select :lesson_end_time %>
</div>
<div class="actions">
<%= f.submit "Add a lesson" %>
</div>
<% end %>
enter image description here

Weird redirection when updating datas

I generated a scaffold for a portfolio via the Rails command, rails g portfolio titre:string, thumbnail:string lien:string description:text. I also added FriendlyId to get a better URL, and that's about all. Here is the 'update' action.
def update
if #portfolio.update(portfolio_params)
redirect_to #portfolio, notice: 'Portfolio mis à jour.'
else
render :edit
end
end
However, when trying to update a project in my portfolio, the submit button tries to get to 'portfolio#update' via patch, but puts a '.' instead of a '/' which gives me No route matches [PATCH] "/portfolios.test-1"
For the route, I only have resources :portfolios
edit : added the form
<%= form_for #portfolio, url: portfolios_path(#portfolio) do |f| %>
<% if portfolio.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(portfolio.errors.count, "error") %> prohibited this portfolio from being saved:</h2>
<ul>
<% portfolio.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :titre %>
<%= f.text_field :titre %>
</div>
<div class="field">
<%= f.label :categorie %>
<%= f.text_field :categorie %>
</div>
<div class="field">
<%= f.label :description %>
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :thumbnail %>
<%= f.file_field :thumbnail %>
</div>
<div class="field">
<%= f.label :lien %>
<%= f.text_field :lien %>
</div>
<div class="actions">
<%= f.submit 'Enregistrer' %>
</div>
<% end %>
I didn't have any other possibilities that doing #portfolio, url: portfolios_path(#portfolio), otherwise Rails considered that '#portfolio' was nil
edit 2 : added the private 'set_portfolio' params
private
# Use callbacks to share common setup or constraints between actions.
def set_portfolio
#portfolio = Portfolio.friendly.find(params[:id])
end
What's wrong with my app ?
portfolios_path is the collection path.
change it portfolio_path should fix it.
<%= form_for #portfolio, url: portfolio_path(#portfolio) do |f| %>
I guess you are going to use this form for creating new portfolio as well, so change it to <%= form_for(#portfolio) %> should fix it and will also work for both cases. form_for will submit to correct path.

Processing two unassociated Rails models' forms in one controller action

I'm creating a Rails app that will take in input from two models and their respective forms, and then log into a website with Mechanize and do hundreds of tasks there.
The first form consists of the user's login information (the username and password, using the model User), and the second one is a long list of term names and their respective definitions (using the model Term and uploaded into the form as an Excel doc).
I have no need to associate these two models (unlike in similar SO questions, which seem to deal with nested models). Once this Mechanize task completes, I will destroy both models' objects from the database.
The two pieces of the app (logging in to the website; and uploading the terms and using them to interact with the website) both work perfectly in separate scripts.
My question is: How can I take in both models' information on one webpage and coordinate the controller(s) accordingly? In this situation, can I create both objects in one controller? (If not, that's fine, as long as there's an alternative; I'm game for whatever will get this to work.)
I'm posting some of my code below. I'm happy to answer any questions you may have. Please keep in mind I am pretty new at Rails, so is not very elegant code:
The User model:
class User < ActiveRecord::Base
attr_accessor :username, :password
end
And the Term model:
class Term < ActiveRecord::Base
attr_accessible :name, :definition
end
In my terms controller (the forms are located in the index action and the script is run in the show action):
def create
#term = Term.new(params[:term])
#user = User.new(params[:user])
if (#term.save && #user.save)
flash[:notice] = "Your terms have been sent for processing."
redirect_to terms_path
else
render :action => 'index'
end
end
def show
#term = Term.all
agent = Mechanize.new
page = agent.get('www.myurl.com')
#log into the website
#user.username = myform.field_with(:id => "userfield").value
#user.password = myform.field_with(:id => "passfield").value
#and then enter the term information into the website's forms
rest of Mechanize code goes here...
end
And in views/terms/index.html.erb:
#the login form:
<%= render 'loginform' %>
#the term file uploader:
<%= form_tag import_terms_path, multipart: true do %>
<%= file_field_tag :file %>
<%= submit_tag "Import" %>
<% end %>
<br>
<table id="terms">
<tr>
<th>Name</th>
<th>Definition</th>
</tr>
#displays the uploaded terms on the index page
<% #terms.each do |term| %>
<tr>
<td><%= term.name %></td>
<td><%= term.definition %></td>
</tr>
<% end %>
</table>
<p><%= link_to 'Update website with these terms', terms_update_terms_path %></p>
And in views/terms/_loginform.erb:
<%= form_for(#user) do |f| %>
<div class="field">
<%= f.label_tag(:username, 'Username') %><br />
<%= f.text_field_tag(:user, :username) %>
</div>
<div class="field">
<%= f.label_tag(:password, 'Password') %><br />
<%= f.password_field_tag(:user, :password) %>
</div>
<% end %>
And in views/terms/_termform.html.erb
<%= form_for(#term) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :definition %><br />
<%= f.text_area :definition %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
If you just need to save the data and truly don't want to associate the models, I would save the Term separately:
<%= form_for #user do |f| %>
<div class="field">
<%= f.label :username, 'Username' %>
<%= f.text_field :username %>
</div>
<div class="field">
<%= f.label :password %>
<%= f.password_field :password %>
</div>
<div class="field">
<%= label_tag :name %>
<%= text_field_tag :name %>
</div>
<div class="field">
<%= label_tag :definition %>
<%= text_field_tag :definition %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Then in your controller:
#term = Term.new
#term.attributes = {
:name => params[:name],
:definition => params[:definition]
}
#term.save
If you are adding multiple term fields to the form, I would consider something like Cocoon, and just add an each loop for saving the Terms in the controller.

Select tag rails

I have a view where I need to show a list of pages (I have a model called Page) and then i need the id of the selected page
I have this code in the view
مهمة جديدة
: <%= form_for :task, :url => {:action=>"create", :controller=>"tasks"}, :html => {:class :
=> "nifty_form"} do |f| %>
<% if #task.errors.any? %>
<div id="error_explanation">
<h2>: عذرا لم نستطع استكمال طلبك</h2>
<ul>
<% #task.errors.full_messages.each do |msg| %>
<li style="color:red;"><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label "اسم المهمة" %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label "وصف المهمة" %><br />
<%= f.text_area :description %>
</div>
<div class="actions">
<button><%= link_to 'العودة الى قائمة المهام', project_tasks_path %></button>
<%= f.submit "مهمة جديدة"%>
</div>
<%= select_tag(:page, options_for_select(['a',1])) %>
<% end %>
#pageslist is a 2d array of the form [['pagename', 1], ..]
The question is how can i access the page_id of the selected page in the controller ?
I tried params[:p_id] but it is not working any help please?
This is what I have in the controller:
#task = Project.find(params[:project_id]).tasks.new(params[:task])
#task.update_attributes({:page_id => params[:p_id]})
Assuming that #pagelist is in a format as you described, then in your view:
<%= select_tag(:page, options_for_select( #pagelist )) %>
You had missed it in your example, and provided only 1d array for options_for_select.
With such prepared view your create action will receive page id in:
params[:page]
it's because you had passed :page as a first argument for select_tag.

formatting a form inside my rails app

I have a rails app with form inside of it. my css file is all ready. i just don't know how to apply the css form classes and ids also to the fields inside of my create action page where
my form_for lives?
<%= form_for #user do |f| %>
<% if #user.errors.any? %>
<div class="error_messages">
<h2>Form is invalid</h2>
<ul>
<% for message in #user.errors.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :email %><br />
<%= f.text_field :email %>
</p>
<p>
<%= f.label :password %><br />
<%= f.password_field :password %>
</p>
<p>
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</p>
<p class="button"><%= f.submit %></p>
<% end %>
my css styles for the form tag and for its fiels as below:
id="phx-signup-form"
e-mail field css style:
class="email-input"
Try
<%= form_for #user, :html => { :id => 'phx-signup-form' } do |f| %>
and
<%= f.text_field :email, :class => 'email-input' %>
You can read more references on http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html
A good place to start is the Rails API documentation.
form_for(#user, html: { id: 'phx-signup-form' })
should put you on the right path.
Your form automatically takes id as new_user if your form is running as new form and takes id as edit_user if your form is running as edit form. So you use id="new_user" or id="edit_user" instead of id="phx-signup-form" in your css depending on condition.
For your form and <%= f.text_field :email, "", :class => 'email-input' %> for emai field. Just try it. It may solve your problem.

Resources