Ruby custom create method - ruby-on-rails

I scaffolded an Authorization(user_id, code, otherparam1, ...) and I want to add a custom_create method to the authorizations_controller which only require a code, the method generating the other parameters. I need this method to work with json or be called in others methods like User.newcustom(code)
def newcustom
case request.method
when :post #post
code = params[:code]
if(code and code != '')
...
respond_to do |format|
if #authorization.save
format.html { redirect_to #authorizations, notice: 'Authorization was successfully created.' }
format.json { render json: #authorizations, status: :created, location: #authorization }
else
format.html { render action: "new" }
format.json { render json: #authorization.errors, status: :unprocessable_entity }
end
end
else #get
respond_to do |format|
format.html
end
end
Here's my newcustom.html.erb
<%= form_tag( newcustom_authorizations_path, :method => :post ) do %>
<div class="field">
<%= text_field_tag :code %>
</div>
<div class="actions">
<%= submit_tag('Get tokens') %>
</div>
<% end %>
But it doesn't work through json, the form. And calling the method newcustom(:code => code) throws me a too many arguments (1 for 0). Any idea ?

for this add the given code to config/routes.rb
resources :authorizations do
collection do
post :newcustom
end
end

Thanks for the help everyone.
I ended up solving my problem filtering the parameters of the create function, then calling my customcreate one.
AND YES I CHEAT :)

Related

Correct way to pass local variables from a controller to a js.erb which renders a partial

I'm trying to implement an edit function for comments using ajax. The function must load a _form.html.erb partial to edit the comment on which the user clicks but I am not able to figure out how to implement the variables used.
def edit
#comment = Comment.find(params[:id])
#post = Post.find_by_id(params[:post_id])
respond_to do |format|
format.html {}
format.json { head :no_content }
format.js { render "edit", :locals => {:#comment => Comment.find(params[:id]), :#post => #post} }
end
end
def update
#comment = Comment.find(params[:id])
#post = Post.find_by_id(params[:post_id])
if #comment.update_attributes(comment_params)
respond_to do |format|
format.html {
flash[:notice] = "Successfully updated comment"
redirect_to post_path(#comment)
}
format.json { head :no_content }
format.js
end
else
respond_to do |format|
format.html {flash[:alert] = "Error updating coment"
render :edit
flash[:alert] = "Error updating coment"
render :edit}
format.json { head :no_content }
format.js
end
end
end
Here are my js files, edit and update:
$('.edit_comment').bind('ajax:success', function() {
$(this).closest('.comment').html("<%= escape_javascript(render partial: 'comments/form', :locals => {:post => #post,:comment => #comment}) %>");});
$('.edit_comment').bind('ajax:success', function() {
$(this).closest('.comment').replaceWith('<%=j render 'comments/comment', post: #post, comment: #comment%>');
});
There must be some problem with the variables I'm using in my controller and in my js files because when I try and edit more than one comment without refreshing I am always editing the first one I clicked on.
In my console the right comment ids are given when I click on edit, however when the form is loaded on the actual page it is using always the first comment that I tried to edit.
EDIT
adding my form partial:
<%= form_for [post, comment], remote: true do |f| %>
<%= f.text_area :body, placeholder: "Add a Comment" %><br/>
<%= f.submit "Post Comment" %>
<% end %>

When a Post comment is made, no more can be created, only shown

I am trying to get a post and comment system working, for this however i want only one comment to be made per post. Only as i am trying to create a system as where content will be displayed followed by a comment 7 times in one post... Example...
program model 1 body content 1
Commentmodel1
program model 1 body content 2
Commentmodel2
program model 1 body content 3
Commentmodel3
.etc.etc.
For Me this is the simplest way of being able todo this by creating 7 different comment models, i know there is probably an easier way but as im new this seems the simplest. However i am struggling getting the one comment model to only allow just one comment to be made.
In this application coach is the user.
Here are the files involved, For the Models, program is the basic Post model, and comments is comments.
programs/Show.html.erb
<p id="notice"><%= notice %></p>
<p>
<b>Title:</b><br />
<%= #program.title %>
</p>
<p>
<b>Body:</b><br />
<%= #program.cweekcomments %>
</p>
<%= link_to 'Edit', edit_program_path(#program) %> |
<%= link_to 'Back', programs_path %>
<br /><br /><br />
<i>Comments</i>
<% #program.comments.each do |comment| %>
<p>
<b>Comment:</b>
<% if comment %>
<%= comment.body %>
<br />
<%= link_to 'Edit', edit_program_comment_path(#program, comment) %> | <%= link_to 'Destroy', [#program, comment] , method: :delete, data: { confirm: 'Are you sure?' } %>
<% else %>
<%= form_for([#program, #program.comments.build]) do |f| %>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<% end %>
</p>
<% end %>
Programs_controller.rb
class ProgramsController < ApplicationController
before_filter :authenticate_coach!, :except => [:show]
# GET /programs
# GET /programs.json
def index
#programs = Program.find_all_by_coach_id(current_coach[:id])
respond_to do |format|
format.html # index.html.erb
format.json { render json: #programs }
end
end
# GET /programs/1
# GET /programs/1.json
def show
#program = Program.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #program }
end
end
# GET /programs/new
# GET /programs/new.json
def new
#program = Program.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #program }
end
end
# GET /programs/1/edit
def edit
#program = Program.find(params[:id])
end
# POST /programs
# POST /programs.json
def create
#program = Program.new(params[:program])
respond_to do |format|
if #program.save
format.html { redirect_to #program, notice: 'Program was successfully created.' }
format.json { render json: #program, status: :created, location: #program }
else
format.html { render action: "new" }
format.json { render json: #program.errors, status: :unprocessable_entity }
end
end
end
# PUT /programs/1
# PUT /programs/1.json
def update
#program = Program.find(params[:id])
respond_to do |format|
if #program.update_attributes(params[:program])
format.html { redirect_to #program, notice: 'Program was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #program.errors, status: :unprocessable_entity }
end
end
end
# DELETE /programs/1
# DELETE /programs/1.json
def destroy
#program = Program.find(params[:id])
#program.destroy
respond_to do |format|
format.html { redirect_to programs_url }
format.json { head :no_content }
end
end
end
Comments_controller.rb
class CommentsController < ApplicationController
def new
#comment = #program.comments.build
end
def create
#program = Program.find(params[:program_id])
#comment = #program.comments.create(params[:comment])
redirect_to program_path(#program)
end
def destroy
#program = Program.find(params[:program_id])
#comment = #program.comments.find(params[:id])
#comment.destroy
redirect_to program_path(#program)
end
def edit
#program = Program.find(params[:program_id])
#comment = #program.comments.find(params[:id])
end
def update
#program = Program.find(params[:program_id])
#comment = #program.comments.find(params[:id])
respond_to do |format|
#if #program.comments.update_attributes(params[:comment])
if #comment.update_attributes(params[:comment])
format.html { redirect_to program_path(#program), notice: 'Comment was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
end
In advance, thanks for your help, much appreciated!
Change your program comment relation to has_one.(has_one :comment in your program.rb)
def create
#program = Program.find(params[:program_id])
if #program.comment
flash[:error] = "Cannot comment more than once"
else
#comment = #program.comments.create(params[:comment])
flash[:notice] = "Comment created"
end
redirect_to program_path(#program)
end

redirect using a form

this form (views/workers/_form.html.erb) redirects me to the index of tasksadmins, after I push the 'create tasksadmin' button.
I want it to redirect me to "workers/index" and change the button to 'update the task'.
how can I do that please?
<%= form_for(#tasksadmin) do |f| %>
<% if #tasksadmin.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#tasksadmin.errors.count, "error") %> prohibited this tasksadmin from being saved:</h2>
<ul>
<% #tasksadmin.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.hidden_field :admin_mail, :value => #tasksadmin.admin_mail %>
<%= f.hidden_field :worker_mail, :value => #worker_mail %>
<%= f.hidden_field :task, :value => #tasksadmin.task %>
<div class="field">
<%= f.label :done %><br />
<%= f.check_box :done %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
and this is my workers_controller:
class WorkersController < ApplicationController
# GET /workers
# GET /workers.json
def index
#tasks_worker = Tasksadmin.where(:worker_mail => "alon.shmiel#gmail.com")
respond_to do |format|
format.html # index.html.erb
format.json { render json: #workers }
end
end
# GET /workers/1
# GET /workers/1.json
def show
#task_worker = Tasksadmin.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #worker }
end
end
# GET /workers/new
# GET /workers/new.json
def new
#worker = Worker.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #worker }
end
end
# GET /workers/1/edit
def edit
#tasksadmin = Tasksadmin.find(params[:id])
#worker_mail = "alon.shmiel#gmail.com"
end
# POST /workers
# POST /workers.json
def create
#worker = Worker.new(params[:worker])
respond_to do |format|
if #worker.save
format.html { redirect_to "#worker", notice: 'Worker was successfully created.' }
format.json { render json: #worker, status: :created, location: #worker }
else
format.html { render action: "new" }
format.json { render json: #worker.errors, status: :unprocessable_entity }
end
end
end
# PUT /workers/1
# PUT /workers/1.json
def update
#worker = Tasksadmin.find(params[:id])
respond_to do |format|
if #worker.update_attributes(params[:worker])
format.html { render action: "index", notice: 'Worker was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #worker.errors, status: :unprocessable_entity }
end
end
end
# DELETE /workers/1
# DELETE /workers/1.json
def destroy
#worker = Tasksadmin.find(params[:id])
#worker.destroy
respond_to do |format|
format.html { render action: "index" }
format.json { render json: #worker }
end
end
end
In your controller, you have to redirect to the appropriate path like so:
def update
redirect_to "workers/index"
end
I would suggest using path helpers so if you have your routes set up as resources, you can do this:
redirect_to workers_path
As for changing the the button text, just change it to:
f.submit("update the task")
You create a form for an object #tasksadmin, which in your WorkersController#edit is set as follows:
#tasksadmin = Tasksadmin.find(params[:id]
This means that that parameter contains an object of class Tasksadmin, if you let rails build the path for the a Tasksadmin, it will send you to the TasksadminsController#update, and that is why your code does not work. You never get to the WorkersController#update. Check your logs to verify that.
Let me be very clear about this: you should not edit Tasksadmin objects in the WorkersController.
I do not understand why you would do that.

rails passing params to view after redirect

I want to pass 2 strings to the view after redirecting.
the controller:
def create
#rating = Rating.new(params[:rating])
respond_to do |format|
if #rating.save
format.html { redirect_to #rating, :notice => 'Got It!' ,
:notice_small => 'Your photo has been uploaded. good luck with it\'s coolness rating!' }
format.json { render :json => #rating, :status => :created, :location => #rating }
else
format.html { render :action => "new" }
format.json { render :json => #rating.errors, :status => :unprocessable_entity }
end
end
end
the view:
<p id="notice" class="big_notice"><%= notice %></p>
<% if defined? notice_small %>
<p id="small_notice" class="small_notice"><%= notice_small %></p>
<% end %>
the notice string goes throw but the notice_small does not, why?
Only :notice and :alert are allowed to be set using redirect_to.
If you want something beyond this, use :flash => { :notice_small => '....' } option for redirect_to or set flash[:notice_small] before redirect_to explicitly.
The redirect looks like it should work as far as I can tell. However, to make it available in your view, the action you're redirecting to would have to take params["notice_small"] and put it in an instance variable. Something like
#notice_small = params["notice_small"]
in the actions, then you could do
<% if defined? #notice_small %>
<p id="small_notice" class="small_notice"><%= #notice_small %></p>
<% end %>

Not saving, no error message

On form submission, it's telling me that it was successfully created but it's not showing any data that was submitted. The database is empty. It's showing "null" values and the same on the actual screen where I should be able to edit the data. Here's a screenshot
Update: I think the problem is that it's making a GET request but I don't know how to fix it. Here's a screen shot of my server doing a get when I clicked the submit
Here's the set up
In the index action of results_controller.rb, I have
def index
#results = Result.all
#blob = Sex.new //==#blob = Sex.new is the one I'm focussing on...
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #results }
end
end
In views/results/index, I have the form
<`%= form_for(#blob) do |f| %>`
<div class="field">
<b>1. solicitor exam was fixed?:</b><br/>
<%= f.label(:solicitorcurve, "it was cooked") %>
<%= f.radio_button(:solicitorcurve, "t") %> </br>
</div>
<div class="field">
<%= f.label(:solicitorcurve, "no it was ok") %>
<%= f.radio_button(:solicitorcurve, "f") %>
</div>
<div class="field">
<%= f.label(:draftingteach, "i give the teaching a grade of _ on a scale of 1 to 6") %>
<%= f.select:draftingteach, 1..6 %> </br>
</div>
In the create action of sexes_controller.rb i have
def create
#sex = Sex.new(params[:blob])
respond_to do |format|
if #sex.save
format.html { redirect_to(#sex, :notice => 'Sex was successfully created.') }
format.xml { render :xml => #sex, :status => :created, :location => #sex }
else
format.html { render :action => "new" }
format.xml { render :xml => #sex.errors, :status => :unprocessable_entity }
end
end
end
In models/sex.rb, there is nothing...
class Sex < ActiveRecord::Base
end
And this is the set up of the database
It looks like the issue is that you're retrieving params[:blob] when you should be looking at params[:sex]. form_for will create fields named after the class of the object. The instance variable name #blob you're using is arbitrary.
...
#sex = Sex.new(params[:sex])
...
This is a good argument for why you probably want to name instance variables for what they are. Less confusion.

Resources