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| %>
Related
I am using rails gem 'best_in_place' and data edit one by one, as clicked perticular field.
how can i active all fields for editable onclick update/edit button?
def update
if m_user[:name].present?
MUser.where(:id => id).update(:name => m_user[:name])
elsif m_user[:gender].present?
MUser.where(:id => id).update(:gender => m_user[:gender])
else
flash[:danger] = 'not updated'
end
end
View code:
<% #user.each do |record| %>
<tr>
<td>
<%= best_in_place record, :name, :as => :input %>
</td>
<td>
<%= best_in_place record, :gender, :as => :select, collection: (MUser.pluck(:id,:gender)) %>
</td>
<%= best_in_place record, :dob, :as => :date, class: 'datepicker1 %>
</td>
</tr>
<% end %>
<%= submit_tag('update',:name => 'update_data', class: 'btn btn-primary btn-sm', :id => 'update_btn') %>
Now data edit like if i edit name it will automatically editable
,but how can I edit when i clicked update/edit button then make all fields active for edit.
As we discussed, you need to do a couple of changes
Add a _user.html.erb partial to render the records with below code.
<td>
<%= user.name %>
</td>
<td>
<%= user.gender %>
</td>
<td>
<%= user.dob %>
</td>
<td>
<%= link_to "Edit", edit_user_path(user), remote: true %>
<td>
Now change your index.html.erb code like below.
<% #users.each do |user| %>
<tr id="record-row-<%= user.id %>">
<%= render prtial: 'user', locals: { user: user } %>
</tr>
<% end %>
Now refresh your page and you will see the User records in table rows.
Add a new partial _user_form.html.erb to render the form and add below code in it.
<td colspan="4">
<%= form_for(#user, remote: true) do |f|
<table>
<tbody>
<tr>
<td><%= f.text_field :name, class: 'form-control' %></td>
<td><%= f.select :gender, MUser.pluck(:gender, :id).uniq, { selected: #user.gender }, class: 'form-control' %></td>
<td><%= f.text_field :name, class: 'form-control datepicker1' %></td>
<td><%= f.submit "Update" %></td>
</tr>
</tbody>
</table>
<% end %>
</td>
Now need to update edit and update actions.
edit action
def edit
#user = User.find(params[:id])
respond_to do |format|
format.js { }
format.html { render 'edit' }
end
end
update action
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(user_params)
format.js { }
format.html { redirect_to #user, notice: 'User was updated successfully.' }
else
format.js { }
format.html { render 'edit' }
end
end
end
private
def user_params
params.require(:user).permit(:name, :gender, :dob)
end
Now you need to create an edit.js.erb file to render the form on selected row.
$("#record-row-<%= #user.id %>").html("<%= escape_javascript(render 'user_form') %>")
And you also need an update.js.erb file to update the table row after updating the user record.
$("#record-row-<%= #user.id %>").html("<%= escape_javascript(render partial: 'user', locals: { user: #user } ) %>")
Now all set. Refresh your page and click on Edit button of a row. A form will appear. Change the value and click on Update button. You will see the updated record.
Let me know if you have nay issues. Happy to help.
First of all this is the error
First argument in form cannot contain nil or be empty
What I have is a Thread model and controller and a Answer model and Controller.
And what I am trying to do is edit the answer on the show page of the thread via a zurb Reveal Modal.
and this what my code looks like
Thread Modal
class Thread < ApplicationRecord
belongs_to :user
has_many :answers
extend FriendlyId
friendly_id :subject, use: :slugged
end
Answer Model
class Answer < ApplicationRecord
belongs_to :user
belongs_to :thread
end
Answer Controller
def edit
#thread = Thread.friendly.find(params[:thread_id])
#answer = #thread.answers.find(params[:id])
render :layout => false
end
def update
#thread = Thread.friendly.find(params[:thread_id])
#answer = #thread.answers.find(params[:id])
respond_to do |format|
if #answer.update(params[:answer].permit(:content))
format.html { redirect_to thread_path(#thread) }
format.json { render :show, status: :ok, location: #answer }
else
format.html { redirect_to #thread, alert: "Unable to save your post" }
format.json { render json: #answer.errors, status: :unprocessable_entity }
end
end
end
Show Thread
<%= render #thread.answers %>
Answer Partial
<% if current_user.present? && current_user.id == answer.user_id %>
<ul class="edit-links pull-right">
<li>
<%= link_to 'Edit', edit_thread_answer_path(answer.thread, answer), :remote => true, class: "edit", "data-open" => "editModal", "data-open-ajax" => edit_thread_answer_path(answer.thread, answer) %>
</li>
<li>
<%= link_to 'Destroy', [answer.thread, answer], method: :delete, data: { confirm: 'Are you sure?' }, class: "destroy" %>
</li>
</ul>
<% end %>
<p>
<%= simple_format answer.content %>
</p>
<div id="editModal" class="reveal" data-reveal>
<%= render :partial => 'answers/edit_form' %>
<button class="close-button" data-close aria-label="Close modal" type="button">
<span aria-hidden="true">×</span>
</button>
</div>
Answer Edit Form Partial
<h1>Edit Answer</h1>
<%= form_for([#thread, #answer]) do |f| %>
<%= f.text_area :content, :rows => "10" %>
<%= f.submit "Update", :class => "button add-thread" %>
<% end %>
I get the error when I try to open a thread#show
its says the error is here
ArgumentError in Threads#show
<%= form_for([#thread, #answer]) do |f| %>
Trace of template inclusion: app/views/answers/_answer.html.erb, app/views/threads/show.html.erb
Any suggestions ? where may the error be ?
In my app there is a list of items which you can upvote. I want to make these votes with AJAX calls.
This is the view:
<ul class="list-groups">
<% #questions.each do |question| %>
<li class="list-group-item">
<%= link_to question.description, question_path(question) %>
<%= form_for(question, :url => url_for(:controller => 'vote', :action => 'vote'), method: :post, html: { class: 'form-inline' }) do |f| %>
<%= f.submit 'Up vote', class: "btn btn-default" %>
<%= f.hidden_field :id, :value => question.id %>
<% end %>
</li>
<% end %>
</ul>
And this the method that does it:
class VoteController < ApplicationController
respond_to :json
def vote
question_id = params[:question][:id]
user_id = current_user.id
vote = Vote.where(["question_id = :q", { q: question_id }]).where(["user_id = :u", { u: user_id }])
respond_to do |format|
if vote.nil?
#vote = Vote.new
#vote.question_id = question_id
#vote.user_id = user_id
#vote.save
format.html { render '/home/index' }
format.json { render :json => { :status => 'ok' } }
else
format.html { render '/home/index' }
format.json { render :json => { :status => 'failed', :msg => 'You already voted' } }
end
end
end
end
If I don't include this format.html { render '/home/index' } I am getting this error:
ActionController::UnknownFormat in VoteController#vote
But I don't want to render the page again, I am just loading the pieces of html that will change after the action with jQuery and ajax.
How can I respond only with the json?
Use respond_with instead of respond_to in your controller action.
respond_with do |format|
respond_to at the top of your controller is designed to work with respond_with in your controller action, whereas respond_to in your controller action ignores the respond_to that you've defined at the top of your controller.
Also make sure you are making a remote call, instead of a normall one if you want your request to go through AJAX.
<%= form_for(question, :url => url_for(:controller => 'vote', :action => 'vote'), method: :post, remote: true, html: { class: 'form-inline' }) do |f| %>
Note the remote: true part that is added as an argument to the form_for helper.
You need to include remote: true in form_for in order to make the call requests AJAX instead of HTML.
<%= form_for(question, :url => url_for(:controller => 'vote', :action => 'vote'), remote: true, method: :post, html: { class: 'form-inline' }) do |f| %>
Check out the Working with JavaScript in Rails documentation for more information.
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.
I implemented a chat system to my app.
It refreshes the list of comments partially when after new comment was submit.
So new added comment pops up without reloading whole page.
It's working fine but the problem is, it won't make input field empty(initialize) after submit :(
How can I make it empty if it succeeded at submitting?
5 seconds Auto-refreshing will be another issue that's preventing.
So I have to care about it, too.
and If possible I want to pop up flash alert 'you cant spam' when the user tried to submit comment within 10 seconds.
Let's assume as if I'm trying to submit comment from Users#show page
views/users/show.html.erb
<%= javascript_tag do %>
jQuery(document).ready(function () {
refreshPartial();
setInterval(refreshPartial, 5000)
});
function refreshPartial() {
$.ajax({
url: "<%= show_user_path(#user) %>/refresh_part",
type: "GET",
dataType: "script",
});
}
<% end %>
......
<span id="chat">
<%= render 'users/comment' %>
</span>
<%= render 'users/comment_input' %>
views/users/_comment.html.erb
<table>
<tr>
<th>ID</th>
<th>PIC</th>
<th>Body</th>
<th>Subject</th>
<th>Posted by</th>
<th>Delete</th>
</tr>
<% #comments.each do |comment| %>
<tr id="<%= dom_id(comment) %>">
<td><%= comment.id %></td>
<td>
<% if comment.comment_icon? %>
<ul class="thumbnails">
<%= image_tag(comment.comment_icon.url(:thumb),:height => 100, :width => 100, :style => 'border:3px double #545565;' ) %>
</ul>
<% end %>
</td>
<td><%= comment.body %></td>
<td><%= comment.subject %></td>
<td><%= comment.user.user_profile.nickname if comment.user.user_profile %></td>
<td>
<%= button_to 'destroy', polymorphic_path([#user, comment]), :data => {:confirm => 'Are you sure?'}, :method => :delete, :disable_with => 'deleting...', :remote => true, :class => 'btn btn-danger' if current_user && current_user.id == comment.user_id %>
</td>
</tr>
<% end %>
</table>
<%= paginate #comments, :window => 4, :outer_window => 5, :left => 2, :right => 2 %>
views/users/_comment_input.html.erb <= This is input form!!!!!
<%=form_for(([#user, #comment]), :remote => true) do |f| %>
<div class="field">
<%= f.label :body %><br />
<%= f.text_field :body %>
</div>
<div class="field">
<%= f.file_field :comment_icon %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
comments_controller.rb
def create
commentable = #community_topic||#community||#user
#comments = commentable.comment_threads.order("updated_at DESC").page(params[:page]).per(5)
#comment = Comment.build_from(commentable, current_user.try(:id), params[:comment][:body])
#comment.comment_icon = params[:comment][:comment_icon]
if #user
#following_users = #user.all_following(order: 'updated_at DESC')
#followed_users = #user.followers
#communities_user = #user.get_up_voted(Community).order("updated_at ASC").page(params[:page]).per(5)
elsif #community
end
last_comment = Comment.where(:user_id => current_user.id).order("updated_at").last
if last_comment && (Time.now - last_comment.updated_at) <= 10.second
flash[:notice] = "You cannot spam!"
render :template => template_for(commentable)
elsif #comment.save
#if #community_topic.empty?
#comments = commentable.comment_threads.order("updated_at DESC").page(params[:page]).per(5)
#comment = commentable.comment_threads.build
respond_to do |format|
format.html { redirect_to [#community, commentable].uniq, :notice => "comment added!" }
format.js do
if #community.present?
render 'communities/refresh_part'
elsif #community_topic.present?
render 'community_topics/refresh_part'
elsif #user.present?
render 'users/refresh_part'
end
end
end
else
render :template => template_for(commentable)
end
end
views/users/refresh_part.js.erb
$('#chat').html("<%= j(render(:partial => 'users/comment')) %>")
Well I assume this is the "body" input you want to empty so basically, just add an id to it like this :
<%= f.text_field :body, :id => "body_input" %>
And in your views/users/refresh_part.js.erb, you can add something like :
$('#body_input').val('');
This should work only if it succeded at submitting because from what I saw, your template is rendered only if the comment is saved.