I have a controller, which saves fine for that specific controller and model (accesspoint). However, i want to save a particular data into another model (radhuntgroup) - which i do not know how.
def create
#accesspoint = Accesspoint.new(params[:accesspoint])
#accesspoint.user_id = current_user.id
o = [('a'..'z'), ('1'..'9'), ('A'..'Z')].map { |i| i.to_a }.flatten
#accesspoint.secret = (0...30).map{ o[rand(o.length)] }.join
respond_to do |format|
if #accesspoint.save
format.html { redirect_to accesspoints_path, notice: 'Access Point has been added.' }
format.json { render json: #accesspoint, status: :created, location: #accesspoint }
else
format.html { render action: "new" }
format.json { render json: #accesspoint.errors, status: :unprocessable_entity }
end
end
end
the above looks fine for accesspoint controller and model (saves all the parameters from form into the accesspoint table) however, i want to save one particular data into another field into the radhuntgroup table.
accesspoint view.
%= simple_form_for #accesspoint, :html => { :class => 'form-horizontal' } do |f| %>
<div class="control-group">
<div class="controls">
<%= f.input :shortname, :label => false, :autofocus => true, :placeholder => 'Access Point Name', :hint => 'example: quadifi_hotspot' %>
</div>
</div>
<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
accesspoints_path, :class => 'btn' %>
</div>
<% end %>
in this case, i hope to duplicate the "shortname" column in the accesspoint table into the radhuntgroup table in the "groupname" column. - which i am looking at using the controller to do this.
If i were to do it in PHP for example, this would be a lot easier but i am dealing with legacy databases which most parts of backend is already "hardcoded" this way and i cannot fully follow the conventions.
Related
I am trying to update a record from the view of another scaffold, the problem is that it sends me the following error:
No route matches {:action=>"update", :controller=>"pedidosliberados"}
I'm showing one form per record
this is my form:
<% #pedidosliberados.each do |pedidoliberado| %>
<tr id="pedido_liberado_<%= pedidoliberado.id %>">
<td class="component_name_body_col"><%=pedidoliberado.try(:Client)%></td>
<td class="component_name_body_col">
<%= form_for(pedidoliberado, :method => :put, remote: true, :url => {:controller =>'pedidosliberados', :action => 'update'}, html: {class: "form-horizontal "}) do |f| %><!--ajax-->
<%= f.text_field :Status, value: "1" %>
<%= submit_tag "Actualizar", class: "btn btn-primary"%>
<% end %>
</td>
</tr>
<% end %>
my route:
resources :pedidosliberados
my action update from controller pedidosliberados:
def update
respond_to do |format|
if #pedidoliberado.update(pedidoliberado_params)
format.html { redirect_to #pedidoliberado, notice: 'Pedidoliberado was successfully updated.' }
format.json { render :show, status: :ok, location: #pedidoliberado
format.js {}
else
format.html { render :edit }
format.json { render json: #pedidoliberado.errors, status: :unprocessable_entity }
format.js {}
end
end
end
The problem is that you are using an incomplete route, that is /update; you need to add the id of the object to be updated, something like /update/12 where 12 is the id of the object. So in your code you could remove the :url attribute and you will be fine.
So your view, now should look like this:
<% #pedidosliberados.each do |pedidoliberado| %>
<tr id="pedido_liberado_<%= pedidoliberado.id %>">
<td class="component_name_body_col"><%=pedidoliberado.try(:Client)%></td>
<td class="component_name_body_col">
<%= form_for(pedidoliberado, :method => :put, remote: true, html: {class: "form-horizontal "}) do |f| %><!--ajax-->
<%= f.text_field :Status, value: "1" %>
<%= submit_tag "Actualizar", class: "btn btn-primary"%>
<% end %>
</td>
</tr>
<% end %>
This works because rails automatically assigns the correct controller and action for your object (when using REST routes).
UPDATE
If you want to explicity assign the url, then use :url like you are doing, but adding :id (remember, you need to specify the id of the object to be updated). So, your form should look something like this:
<%= form_for(pedidoliberado, method: :put, remote: true, url: { controller: 'pedidosliberados', action: 'update', id: pedidoliberado.id }, html: { class: "form-horizontal " }) do |f| %>
I have a form which allows a user to invite multiple people via adding emails in a comma separated list. In my "Participant" model, I have a call to validate the uniqueness of the email entered (scoped by "project_id"). In the model validation, it gives a place to explain the error (message), but I can't get that error to show up on my form if the validation fails.
If a user enters the email of a person that has already been added, how can I get the errors message to render?
participant.rb
class Participant < ActiveRecord::Base
validates :email, uniqueness: {case_sensitive: false, scope: :project_id, message: "Looks like you\'ve already added this person."}
end
participant_controller.rb
def new_participant
#new_participants = Participant.new
#participants = Participant.where(project_id: #project.id).includes(:user)
#template = Template.find(#project.template_id)
#address = Address.where(project_id: #project.id).first
#food = ProjectRestriction.where(project_id: #project.id)
end
def add_participant
#added_by = User.find(current_user.id)
#new_participants = params[:new_participants][:email].split(/,\s*/)
#new_participants.each do |t|
newpart = Participant.new(:email => t, :project_id => #project.id, :level => 4,
:participant_cat_id => 2, :last_updated_by => current_user.id, :added_by => current_user.id, :status => 'unseen')
respond_to do |format|
if newpart.save
ProjectMailer.notify_recipient(newpart, #project, #added_by, #participant_invite ).deliver_later
self.response_body = nil
redirect_to participants_path(p: #project.id, w: 'recipient')
else
format.html { redirect_to new_participant_path(p: #project.id)}
format.json { render json: #new_participants.errors, status: :unprocessable_entity }
end
end
end
end
form
<%= form_for :new_participants, url: add_participant_path( :p => #project.id), html: { :multipart => true, :class=> "form-horizontal", id: "basicForm" } do |f| %>
<% if #new_participants.errors.any? %>
<h2>OOPS!</h2>
<ul>
<% #new_participants.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul></div>
<% end %>
<div class="form-group ">
<label class="form-label dk-aqua"> Email: <span class="asterisk">*</span></label>
<%= f.text_field :email, :autofocus => true, :required => true, :maxlength => 55, :placeholder => 'Email(s)', :class => 'form-control' %>
</div>
<%= f.submit 'INVITE', :class => 'btn btn-aqua btn-lg btn-block',
:style => 'margin-bottom:-5px' %>
<% end %>
Your main issues are:
you are creating a respond block for each email in the request. 1 request = 1 response.
The objects in stored in memory in #new_participants are not actually saved.
In your views your are treating #new_participants as if it where a single resource.
Pay attention to pluralization when naming routes, variables and actions.
def add_participants
#added_by = User.find(current_user.id)
#new_participants = params[:new_participants][:email].split(/,\s*/)
#new_participants.map do |email|
newpart = Participant.new(
:email => email,
:project_id => #project.id,
:level => 4,
:participant_cat_id => 2,
:last_updated_by => current_user.id,
:added_by => current_user.id,
:status => 'unseen'
)
if newpart.save
ProjectMailer.notify_recipient(newpart, #project, #added_by, #participant_invite ).deliver_later
end
new_part
end
#invalid = #new_participants.reject(&:valid?)
if #invalid.any?
respond_to do |format|
format.html { redirect_to new_participant_path(p: #project.id)}
format.json { render json: #new_participants.map(&:errors), status: :unprocessable_entity }
end
else
respond_to do |format|
redirect_to participants_path(p: #project.id, w: 'recipient')
end
end
end
<ul>
<% #new_participants.each |p| %>
<% p.errors.messages.each do |msg| %>
<li><%= msg %></li>
<% end if p.errors.any? %>
<% end %>
</ul>
When I get an error creating a quote, it renders the same page it was just on and displays the errors. Unfortunately two inputs are drop down menus of strings, and they disappear when the refresh happens.
I've looked at Rail 3: instance variable not available after redirection which talks about sessions, which looks like it could be the right way to go but I'm not sure. Any help would be appreciated.
quotes controller
def new
#quote = Quote.new
#quote.items.build
#types = ["T-Shirt", "Hoodie", "Sweatpants"]
#colors = ["White", "Black", "Red", "Blue", "Green"]
end
def create
#quote = Quote.new(params[:quote])
respond_to do |format|
if #quote.save
format.html { redirect_to root_url }
flash[:success] = "Your quote is being approved. You will recieve an email shortly!"
format.json { render json: #quote, status: :created, location: #quote }
else
format.html { render :action => 'new' }
format.json { render :json => #quote.errors, :status => :unprocessable_entry }
flash[:error] = "Quote failed to create! Try again!"
end
end
end
form partial
<!-- item form -->
<%= f.input :make, collection: #types, label: 'Thread Type' %>
<%= f.input :amount, label: 'How Many' %>
<%= f.input :color, collection: #colors %>
<!-- nested form for creating a design of an item -->
<%= f.simple_fields_for :designs, :html => { :multipart => true } do |designform| %>
<%= render "customdesign", g: designform %>
<% end %>
<!-- add/remove another design -->
<%= f.link_to_add "Add Design", :designs %>
<%= f.input :note, :input_html => { :cols => 50, :rows => 3 }, label: 'Special Notes or Requests' %>
<%= f.link_to_remove "Remove" %>
#colors and #types are only set in the new action, and not the create action. Rendering a template does not automatically call the action method in the controller; it goes straight to the view.
A possible solution is to define helper methods for these lists:
# app/helpers/quote_helper.rb
module QuoteHelper
def possible_types
["T-Shirt", "Hoodie", "Sweatpants"]
end
end
And in your view:
<%= f.input :make, collection: possible_types, label: 'Thread Type' %>
I need ruby to either take the value from an f.select or an f.text_field if 'other' is chosen in the select form. how is this possible?
in the view:
<div class="field">
Parent</br>
<% f.label :parent1 %>
<%= select("jobs","parent1_id",["None","8.5x11","shells"]) %>
Other:
<% f.label :parent2 %>
<%= text_field("jobs","parent2_id") %>
</div>
in the controller:
def create
#job = Job.new(params[:job])
if params[:parent1_id] == "None" #params[:option1_id].nil? #params.has_key?(:option1_id) #Take your pick
#job.parent = params[:parent2_id]
else
#job.parent = params[:parent1_id]
end
respond_to do |format|
if #job.save
format.html { redirect_to #job, :notice => 'Job was successfully created.' }
format.json { render :json => #job, :status => :created, :location => #job }
else
format.html { render :action => "new" }
format.json { render :json => #job.errors, :status => :unprocessable_entity }
end
end
end
The simplest way around the problem would be to use {:include_blank => "none"} in the select, and check if its parameter is null in the controller, if it is then use the other parameter.
How I personally used it:
<%= form_for #thing, :html => { :class => 'form-horizontal' } do |f| %>
.....
<div class="field">
<%= f.label :name %><br />
<%= select_tag "count", "<option>None</option><option>8.5x11</option><option>shells</option>".html_safe %>
</div>
<div class="field">
<%= f.label :name %><br />
<%= text_field_tag "users" %>
</div>
........
<div class="form-actions">
<%= f.submit "Submit", :class => 'btn btn-primary' %>
.......
</div>
<% end %>
Note collection_select is a variation on select where I pass in another model's items.
In the controller:
def create
.......
if params[:option1_id] == "" #params[:option1_id].nil? #params.has_key?(:option1_id) #Take your pick
#thing.attribute = params[:option2_id]
else
#thing.attribute = params[:option1_id]
else
end
Couldn't find Submission without an ID
This problem has haunted me for last few days, and I can't seem to fix it.
This problem occurs when I try to create an Emailinterest object in the app.
I have two models.
Submission
Emailinterest
For every submission, there can be several emailinterest, but emailinterest cannot exist
C:\Rails\actuirl5\app\controllers\emailinterests_controller.rb
submission_id actually a member of emailinterest object. submission_id is suppose to contain the ID value of submission object.
def create
#emailinterest = Emailinterest.new(params[:emailinterest])
#submission = Submission.find(params[:submission_id])
respond_to do |format|
if #emailinterest.save
Notifier.emailinterest_notification(#emailinterest, #submission).deliver
format.html { redirect_to(#emailinterest, :notice => 'Email was successfully sent!') }
format.xml { render :xml => #emailinterest, :status => :created, :location => #emailinterest }
else
format.html { render :action => "new" }
format.xml { render :xml => #emailinterest.errors, :status => :unprocessable_entity }
end
end
end
C:\Rails\actuirl5\app\views\submissions\show.html.erb
....
<%= render :partial=>"form_new_emailinterest", :locals=>{:emailinterest=>Emailinterest.new(:submission_id=>#submission.id)} %>
C:\Rails\actuirl5\app\views\submissions
<%= form_for(emailinterest) do |f| %>
<%= hidden_field :submission_id, :value => #submission.id %>
<div class="field">
<%= f.label :sender_email %><br />
<%= f.text_field :sender_email %>
</div>
<div class="field">
<%= f.label :sender_email_content %><br />
<%= f.text_area :sender_email_content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
FIX
C:\Rails\actuirl5\app\controllers\emailinterests_controller.rb
def create
#emailinterest = Emailinterest.new(params[:emailinterest])
#submission = Submission.find(params[:submission_id])
respond_to do |format|
if #emailinterest.save
Notifier.emailinterest_notification(#emailinterest, #submission).deliver
format.html { redirect_to(#emailinterest, :notice => 'Email was successfully sent!') }
format.xml { render :xml => #emailinterest, :status => :created, :location => #emailinterest }
else
format.html { render :action => "new" }
format.xml { render :xml => #emailinterest.errors, :status => :unprocessable_entity }
end
end
end
C:\Rails\actuirl5\app\views\submissions_form_new_emailinterest.html.erb
<%= form_for(emailinterest) do |f| %>
<%= hidden_field_tag :submission_id, value = #submission.id %>
<div class="field">
<%= f.label :sender_email %><br />
<%= f.text_field :sender_email %>
</div>
<div class="field">
<%= f.label :sender_email_content %><br />
<%= f.text_area :sender_email_content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
C:\Rails\actuirl5\app\views\submissions\show.html.erb
<%= render :partial=>"form_new_emailinterest", :locals=>{:emailinterest=>Emailinterest.new} %>
Considering you have set #submission in your show action this should work:
<%= hidden_field :submission_id, :value => emailinterest.submission_id %>
and then
#submission = Submission.find(params[:emailinterest][:submission_id])
You cannot access instance variables like #submission in a partials. This is why you have the option :locals.