Setting an object attribute from a hidden field Ruby on Rails - ruby-on-rails

I'm trying to update an Idea attribute challenge_id through a hidden form field. Here is the field:
<%= f.hidden_field :challenge_id, :value => #challenge.id %>
It successfully passes the challenge id as a param when an idea is created to the Idea Controller#create method:
Started POST "/ideas.js" for ::1 at 2015-06-18 15:39:49 -0400
Processing by IdeasController#create as JS
Parameters: {"utf8"=>"✓", "idea"=>{"title"=>"adsf", "description"=>"asf", "domain_tokens"=>"20", "challenge_id"=>"5"}, "commit"=>"Create Idea"}
This challenge_id => 5 should then be saved to the idea in the line #idea = Idea.new(idea_params) below:
ideas_controller.rb
def create
#idea = Idea.new(idea_params)
respond_to do |format|
if #idea.save
idea_count = #idea.user.ideas_created_count
#idea.user.update(:ideas_created_count => idea_count + 1)
#idea.domains.each do |domain|
current_user.add_points(1, category: domain.title)
end
#ideas = current_user.current_team.ideas.sort_by{|i| i.heat_index}.reverse
#ideas = #ideas.paginate(:page => params[:ideas_page], :per_page => 10)
format.html { redirect_to :back, notice: 'Idea was successfully created.' }
format.json { render :show, status: :created, location: #idea }
format.js
else
format.html { redirect_to :back, notice: "You must attach domains to your Idea." }
format.json { render json: #idea.errors, status: :unprocessable_entity }
format.js { render :create_failed }
end
end
end
.
.
def idea_params
params.require(:idea).permit(:title, :description, :challenge_id)
end
However, this challenge id isn't being saved to the idea with the other permitted idea_params, :title and :description. How can I get challenge_id to be saved to the Idea when it's created?

Instead of using hidden field, why not pass in the challenge_id in your form? Otherwise, you leave open the possibility that users can enter whatever they want in that hidden field.
Form:
form_for [#challenge, Idea.new] do |f|
And then:
def create
#challenge = Challenge.find(params[:challenge_id])
#idea = Idea.new(idea_params)
#idea.challenge_id = #challenge.id
end

I'm assuming you have challenge_id column in ideas table.
Try something like:
def create
#idea = Idea.new(idea_params)
#idea.challenge_id = params[:idea][:challenge_id]
#...
end
If you params or column you want to save it to is different, make sure to make the change, but you get the idea.

Related

Rails 4 is not saving into the database with this method?

Trying to save parameters from url into a database.
I have a link:
- #kits.each do |kit|
= link_to 'Submit Video', new_challenge_path(kit: kit)
#this will append a new parameter into the url
The link goes to a form page with this:
= simple_form_for #challenge, html: { class: "form-horizontal" } do |f|
= f.input :video_title
= f.input :video_url
= f.input :video_desc, as: :text
= f.button :submit, "Upload video"
In my controller, I have this:
def create
#challenge = Challenge.new(challenge_params)
#challenge.kit_id = params[:kit]
respond_to do |format|
if #challenge.save
format.html { redirect_to #challenge, notice: 'Challenge was successfully created.' }
format.json { render :show, status: :created, location: #challenge }
else
format.html { render :new }
format.json { render json: #challenge.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_challenge
#challenge = Challenge.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def challenge_params
params.require(:challenge).permit(:video_title, :video_url, :video_desc, :kit_id)
end
Association between kit and challenge
class Challenge < ActiveRecord::Base
belongs_to :kit, counter_cache: true
end
class Kit < ActiveRecord::Base
has_many :challenges
end
The parameter doesn't save into the :kit_id. Doesn't this: #challenge.kit_id = params[:kit] supposed to take care of saving it?
You are right to do the kit_id assignment in controller, not in the form, since doing so in the form (even by means of using the hidden field) is not secure, because changing the value of a hidden_field is just a matter of inspecting the elements of the page.
What you are doing wrong, is I assume that params[:kit] is just nil.
You would probably want to use params[:kit_id].
If that won't help, put binding.pry here:
# ... code omitted
#challenge.kit_id = params[:kit]
binding.pry
# ... code omitted
and check the value of params in opened console.

Passing variable to the url in rails

I am passing variable like that:
new_sub_request_path(request_id:#request.id)
so i get this url:
http://localhost:3000/sub_requests/new?request_id=1
In my controller i want to assign that request_id like that:
#sub_request = SubRequest.new(sub_request_params)
#sub_request.request_id = params[:request_id]
and my strong parameters are defined:
def sub_request_params
params.require(:sub_request).permit(:description, :diagnos, :price, :payment, :request_id)
end
But after save i have empty request_id attribute, so it seems that it is not assigned. What am I doing wrong?
EDIT:
Inspecting parameters in the console showed that i only have those attributes that are in my form.
EDIT2:
def create
#sub_request = SubRequest.new(sub_request_params)
#sub_request.request_id = params[:sub_request][:request_id]
respond_to do |format|
if #sub_request.save
format.html { redirect_to #sub_request, notice: 'Sub request was successfully created.' }
format.json { render :show, status: :created, location: #sub_request }
else
format.html { render :new }
format.json { render json: #sub_request.errors, status: :unprocessable_entity }
end
end
end
You have to define something like below for the request_id to save in sub_requests table.
In your create method add this line
#request = Request.find(params[:request_id]) and do
#sub_request.request_id = #request.id
or
You can just add a hidden_field in your form like below
<%= f.hidden_field :request_id, :value => #request.id %>
And make sure you are permitting :request_id in your sub_request_params

Rails Type Mismatch Issue

I'm following this answer: https://stackoverflow.com/a/8753998/561634 and trying to make a user_post_id based on the user just like described in the answer.
The end goal is to have urls like website.com/username/posts/4 where 4 is the 4th post from that specific user, instead of like now where website.com/username/posts/4 would show the 4th post in the database.
I'm getting this error:
ActiveRecord::AssociationTypeMismatch in PostsController#create User(#2171866060) expected, got String(#2152189000)
my controller create method looks like this:
def create
#post = Post.new(post_params)
#post.user = current_user.id
respond_to do |format|
if #post.save
format.html { redirect_to post_path(username: current_user.username, id: #post.id), notice: 'Post was successfully created.' }
format.json { render action: 'show', status: :created, location: #post }
else
format.html { render action: 'new' }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
my model looks like this:
before_save :set_next_user_post_id
validates :user_post_id, :uniqueness => {:scope => :user}
def to_param
self.user_post_id.to_s
end
belongs_to :user
private
def set_next_user_post_id
self.user_post_id ||= get_new_user_post_id
end
def get_new_user_post_id
user = self.user
max = user.posts.maximum('user_post_id') || 0
max + 1
end
Thanks for all help!
This line:
#post.user = current_user.id
Should either be #post.user = current_user or #post.user_id = current_user.id

How do I change the form rendered by Rails?

I have two classes, User and Contact. A User has many contacts, and a Contact belongs to a user. In the user's show view, I have:
<%= link_to 'Add Contact', :controller => "contacts", :action => "new", :user => #user.id %>
Then, in the contact's controller, under the new action, I have:
#user = User.find(params[:user])
#contact = Contact.new
#contact.user = #user
When the new contact form renders, it has #<User:0x4c52940> in the User field already. However, when I go to submit the form, I get the error: User(#39276468) expected, got String(#20116704).
The problem is that, when create gets called, Ruby takes everything in the form and overwrites the fields in the new Contact. So: how can I change the form to remove the User field, so that the User is not overwritten with the string?
Edit:
My Contact's new.html.erb has this:
<%= render 'form' %>
<%= link_to 'Back', contacts_path %>
Contact's controller:
def new
#user = User.find(params[:user])
#contact = Contact.new
#contact.user = #user
respond_to do |format|
format.html # new.html.erb
format.json { render json: #contact }
end
end
and
def create
#contact = Contact.new(params[:contact])
respond_to do |format|
if #contact.save
format.html { redirect_to #contact, notice: 'Contact was successfully created.' }
format.json { render json: #contact, status: :created, location: #contact }
else
format.html { render action: "new" }
format.json { render json: #contact.errors, status: :unprocessable_entity }
end
end
end
I believe you misuse create action of the controller. Essentially its content should be like so
def create
#user = User.find(params[:user_id])
contact = #user.contacts.build(params[:contact])
if contact.save
flash[:alert] = 'New contact is created'
redirect_to contacts_path(contact)
else
flash.now[:error' = 'Error creating contract'
render :action => :new
end
end
So +1 for the previous answer - show you controller and new form code

Rails - passing session info in hidden fields - getting error

I'm trying to pass a project id from a session in a hidden field on a task form, so that when the task is created, it has the id of the project that it is assigned to. I've done this before fine, and have even tried copying over the code that I used from when it worked, but changing names and I'm getting errors no matter what I do - if anyone could help point out where I'm going wrong, it would be much appreciated, thanks!
The error I'm getting with this configuration is: "unknown attribute: project_id"
View Code (tasks/_form):
<%= form_for(#task) do |f| %>
<div class="field">
<%= f.hidden_field :project_id, :value => session[:project_id] %>
</div>
...
<% end %>
Model Code (task):
attr_accessible :project_id
belongs_to :project
Controller code (tasks_controller):
def new
#task = Task.new
#project_id = session[:project_id]
respond_to do |format|
format.html # new.html.erb
format.json { render json: #task }
end
end
def create
project_id = session[:project_id]
#task = Task.new(params[:task])
respond_to do |format|
if #task.save
format.html { redirect_to #task, notice: 'Task was successfully created.' }
format.json { render json: #task, status: :created, location: #task }
else
format.html { render action: "new" }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
Here's the application trace - it is pointing to line 46, which in my code is the '#task = Task.new(params[:task])' line in the create action...?
app/controllers/tasks_controller.rb:46:in `new'
app/controllers/tasks_controller.rb:46:in `create'
Does the Task model have a project_id column?

Resources