too few arguments with scaffold code - ruby-on-rails

The join method below in the teams_controller.rb is sent the following data through submission of a form using EmberJs
{"id"=>"3", "user_id"=>"42", "action"=>"join", "controller"=>"teams"}
The record is getting created with the join method below (according to the console), but the code for what happens after the save is throwing an error
ArgumentError (too few arguments):
app/controllers/teams_controller.rb:145:in `format'
app/controllers/teams_controller.rb:145:in `join'
I copied the code following the #team.save method from the Rails scaffold generator, so I'm a little surprised. The hope is that it will respond with the json, but I left in the html format just because (maybe there's a graceful degradation benefit). Can you tell me why that error's being thrown and/or how I could avoid it?
Rails method
def join
#team = Team.find(params[:id])
id = params[:user_id]
#team.user_ids = #team.user_ids.push(id)
if #team.save
format.html { redirect_to #team, notice: 'Joined Team' }
format.json { render json: #team, status: :created, location: #team }
else
format.html { render action: 'new' }
format.json { render json: #team.errors, status: :unprocessable_entity }
end
end
Update,
I should also note that, based on the line number of the error message, the method seems to be treating the format as html, however, I wanted it to be treated as json

I forgot to put respond_to do |format| around the code.
respond_to do |format|
if #team.save
format.html { redirect_to #team, notice: 'Joined Team' }
format.json { render json: #team, status: :created, location: #team }
else
format.html { render action: 'new' }
format.json { render json: #team.errors, status: :unprocessable_entity }
end
end

Related

Passing current user parameters into nested model

I am trying to pass through a devise user id from my Agent model (current_agent.id) into my Nested AgentActivity model whenever I update the parameters on my Submission model. How would I go about achieving this?
Currently my code on Submission controller (doesn't throw an error but doesn't do anything):
#submission.agent_activities.first.agent_id = current_agent.id
respond_to do |format|
if #submission.update(submission_params)
format.html { redirect_to #submission, notice: 'Submission was successfully updated.' }
format.json { render :show, status: :ok, location: #submission }
else
format.html { render :edit }
format.json { render json: #submission.errors, status: :unprocessable_entity }
end
end
Yes, you're just assigning agent_id, but don't saving it. Should be:
#submission.agent_activities.first.update(agent_id: current_agent.id)
And this line should go after if #submission.update(submission_params)

rails - URL doesn't match with the view

I have something strange in my rails app, I try to redirect the user to a specific page if a form is wrong formatted. It works but the URL does not match to the view.
I use files generated by rails g scaffold User. I added specific condition in model file to check user input to see if the form is well formatted or not and if not, it redirect him to the connection view.
I redirect him between 2 different controllers
So i turned this (app/controller/users_controller.rb):
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to root_path, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
into this:
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to root_path, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: #user }
else
format.html { render :template => 'pages/connection' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
I tried and i'm well redirected to pages/connection.rb but the url in my browser is : http://url:8080/users and not http://url:8080/connection. So if i refresh, it leave pages/connection.rb to users/.
Also, error messages from model/user.rb aren't displayed.
what's wrong in my code ?
You are rendering the template pages/connection, you are not redirecting the user to the other controller.
format.html { render :template => 'pages/connection' }
Render and redirect are not the same

Passing an argument on request.referrer

I'm building a site where a link to fill a new form can be clicked from an Event show page
<%= link_to 'Be a Contestant', new_form_path(:event_id => #event.id)%>
This creates a link like
http://localhost:3000/forms/new?event_id=2
Now if the form is filled with an error, when submitted, it returns an error
Couldn't find Event with 'id'=""
So I decided to use the request.referrer to redirect back to the previous page but it doesn't list the errors as use this method
def create
#form = Form.new(form_params)
respond_to do |format|
if #form.save
format.html { redirect_to #form, notice: 'Form was successfully created.' }
format.json { render :show, status: :created, location: #form }
else
format.html { redirect_to request.referrer }
format.json { render json: #form.errors, status: :unprocessable_entity }
end
end
end
I also tried this but to no avail.
def create
#form = Form.new(form_params)
respond_to do |format|
if #form.save
format.html { redirect_to #form, notice: 'Form was successfully created.' }
format.json { render :show, status: :created, location: #form }
else
format.html { redirect_to new_form_path(:event_id => request.referrer.params[:event_id]) }
format.json { render json: #form.errors, status: :unprocessable_entity }
end
end
end
What you probably really need to do is to add a hidden field event_id to the form because I'm betting that event_id doesn't get propagated from the #new to the #create action.
See here for more information on hidden_field_tag
You usually just render the edit view when there was an error in create:
def create
#form = Form.new(form_params)
respond_to do |format|
if #form.save
format.html { redirect_to #form, notice: 'Form was successfully created.' }
format.json { render :show, status: :created, location: #form }
else
format.html { render :edit, alert: 'Error creating ...' }
format.json { render json: #form.errors, status: :unprocessable_entity }
end
end
end

Rails - ActionController::Parameters include controller value with form values

I have a session variable (user_id) that I'd like to include as a foreign key on a record the user is inserting. I have the form values all coming through the form submit to my controller's entity.update(params) method without a problem using the default params definition. That code looks like
def brand_params
#brand_params = params.require(:brand).permit(:name, :brand_type, :profile_id)
end
The update method looks like
if #brand.update(brand_params)
format.html { redirect_to #brand, notice: 'Widget was successfully updated.' }
format.json { render :show, status: :ok, location: #brand }
else
format.html { render :edit }
format.json { render json: #brand.errors, status: :unprocessable_entity }
end
Now I'd like to append the :profile_id session variable to the #brand_params and following other threads here, I've tried a setter method:
def set_brand_params(key, val)
if #brand_params != nil
#brand_params[key] = val
end
end
However, calling this, #brand_params is always nil. Trying to directly add to the brand_params hash doesn't work because it's a better method. If there's a better way to meet this (I'd assume common) use case, I'm all ears! Otherwise, I'd like to know why the var is always nil though in this context, at least the brand_params method sees it as defined and with value. I got this solution in Adding a value to ActionController::Parameters on the server side
Here is the update method as requested:
def update
puts "update"
set_brand_params("profile_id", session[:prof])
respond_to do |format|
if #brand.update(brand_params)
format.html { redirect_to #brand, notice: 'Widget was successfully updated.' }
format.json { render :show, status: :ok, location: #brand }
else
format.html { render :edit }
format.json { render json: #brand.errors, status: :unprocessable_entity }
end
end
end
I'm not agree with merge your data with the params. Because you must permit only the fields you expect your user update. In this case you don't want the user update profile_id on brands, and that is a security best practice.
Then brand_params must be:
def brand_params
#brand_params = params.require(:brand).permit(:name, :brand_type)
end
Your method update may look by this:
def update
#brand = Brand.find(params[:id])
#brand.assign_attributes(profile_id: session[:prof])
respond_to do |format|
if #barnd.update(brand_params)
format.html { redirect_to #brand, notice: 'Widget was successfully updated.'}
format.json { render :show, status: :ok, location: #brand }
else
format.html { render :edit }
format.json { render json: #brand.errors, status: :unprocessable_entity }
end
end
end
You don't need the method set_brand_params at all.
If this don't do the trick, please publish the entry controller, and I hope we find the issue.
edit: add respond_to.

Rails Template Missing

I recently updated a controller from a plain
render :json => #something
to
respond_to do |format|
format.html {
redirect_to #something
}
format.json {
puts "found json format"
format.json { render json: #something, status: :created }
}
end
But, now I'm getting ActionView::MissingTemplate errors. My question is, if I use the respond_to do |format| block, am I required to use a template? What if I just want to return plain json?
Btw, the puts statement in the json respond_to block is being called successfully.
I think the problem is puts being called inside of your format.json block and the nesting of format.json inside of it's own block. Try removing both (as below).
respond_to do |format|
format.html {
redirect_to #something
}
format.json {
puts "found json format"
format.json { render json: #something, status: :created }
}
end
Try:
respond_to do |format|
format.html { redirect_to #something }
format.json { render json: #something, status: :created }
end
You are telling that you accept HTML and JSON formats. Since your request comes from HTML you'll have the HTML template rendered.
If you want to return only JSON remove that line from your code. Also check the docs on respond_to.
Probably you already know it, but there's a guide on Layouts and Rendering.
Remove the format.json part from within the json rendering block (you have an unnecessary block within your block):
respond_to do |format|
format.html {
redirect_to #something
}
format.json {
render json: #something, status: :created
}
end
I think the reason your code is prompting an error it's because you have
format.json {
format.json { render json: #something , status: :created }
}
You should have:
format.json {
render json: #something , status: :created
}

Resources