Assign variable to user input in Rails view - ruby-on-rails

In my view,the user needs input some data using collection_select.
I know the data can be accessed using params[] in the controller.
But how do I access the value the user right after has selected a value?
This is what I am trying to do(doesnt work):
<%= f.collection_select :photo_type, Upload::PHOTOTYPE, :to_s, :to_s, :include_blank => false, :id => "phototype"%>
<%= f.hidden_field :photo_id, :value => Photo.find_by_type(params[:photo_type]).id %>
My question is how do I access the :photo_type in the collection_select?
EDIT
I have tried using jQuery but I don't know how to export the js variable to the view:
<script type="text/javascript">
$("#phototype").change(function() {
var phototype = $('#phototype').val()
});
</script>
UPDATE
I have two tables in my database:
Table 1: photos
id
photo_type_id (refer to id in the photo_types table)
Table 2: photo_types
id
photo_type
User can select photo type from the drop down menu, and I want to find the photo_type_id in the photo_types table by the user input and then insert the photo_type_id into the photos table
According to codeit, I changed my controller like this:
def create
#photo = photo.new(params[:photo])
photo_type_id = PhotoType.find_by_type(params[:photo_type]).id
respond_to do |format|
if #photo.save
format.html { redirect_to #photo, notice: 'photo was successfully created.' }
format.json { render json: #photo, status: :created, location: #photo }
else
format.html { render action: "new" }
format.json { render json: #photo.errors, status: :unprocessable_entity }
end
end
end

I think you are using hidden_field to send value to next action. Why don't you do the same in controller action:
def create
#photo = Photo.new(params[:photo])
#photo.photo_type_id = PhotoType.find_by_type(params[:photo][:photo_type]).id
respond_to do |format|
if #photo.save
format.html { redirect_to #photo, notice: 'photo was successfully created.' }
format.json { render json: #photo, status: :created, location: #photo }
else
format.html { render action: "new" }
format.json { render json: #photo.errors, status: :unprocessable_entity }
end
end
end
View:
<%= f.collection_select :photo_type, Upload::PHOTOTYPE, :to_s, :to_s, :include_blank => false, :id => "phototype"%>
Suggestion: Standard practice is avoiding queries in views.

Related

How to create a method for specific values in a column from a table?

Issue: I am looking for a way to have separate notices for different values in a tables column.
I have order_status that has 3 separate values, created, cancelled, and charged.
I would like 3 separate notices for each when the columns are changed from a view.
a view will be something like:
<%= form_for #order, remote: true do |f| %>
<%= f.hidden_field :order_status, value: "cancelled" %>
<%= f.button type:'submit', class: "btn btn-danger" %>
<% end %>
This will change the column to "cancelled".
I then want to create a method like:
def cancel_update
respond_to do |format|
if #order.update(params[:order_update])
if user_signed_in?
if #order.order_status = "cancelled"
format.html { redirect_to #order, notice: 'Order was successfully cancelled.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
end
end
But this method didn't work how i planned. When i use this method, nothing happens when i click the button, no page reload, redirect, etc. I get the error: "The action 'update' could not be found for OrdersController"
(This was tested by taking out the original update method - which is below).
Now when i use this update method, it works but doesn't pin point the value update on the order_status only.
def update
respond_to do |format|
if #order.update(order_params)
if user_signed_in?
format.html { redirect_to #order, notice: 'Order was successfully uploaded.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
if buyer_signed_in?
format.html { redirect_to #order, notice: 'Order was successfully updated.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
end
Here is another attempt that somehow didn't function:
def order_cancel
respond_to do |format|
if #order.update(order_status)
format.html { redirect_to #order, notice: 'Order was successfully cancelled.' }
format.json { head :no_content }
end
end
end
private
def order_status
params.permit(:order_status)
end
How can I pin point the order_status values from the controller to allow me to have separate actions and notices when the values are changed by a end user?
Given that you use the Rails form builder to generate the form's HTML
<%= form_for #order, remote: true do |f| %>
<%= f.hidden_field :order_status, value: "cancelled" %>
I would expect that the generated name of the input field is nested under order. That said you will need to follow these nesting when permitting the params:
def order_status
params.require(:order).permit(:order_status)
end
When you are unsure how the parameters really look like you might want to have a look at the generated HTML structure of the form or you can look at the Rails logs for the update request to the application.
So, those three lines are wrong:
if #order.update(params[:order_update])
if user_signed_in?
if #order.order_status = "cancelled"
Should be:
if user_signed_in?
if #order.update(status: params[:order_status])
if #order.order_status == "cancelled"
But actually should be #order.update!(status: :cancelled) in a cancel action, or at least have a state machine to validate that the user is not messing up the states of the orders.
Or like is expected by your form, those should be in a update method (not cancel_update)
The update method you posted doesn't make sense, it has a minimum of 2 renders, I think you meant to not have the buyer_signed_in section.

Rails time_select custom behavior edit

I have a form with a time_select input field. I am manipulating the data in the controller and storing as integer.
In the view
<%= f.label :duration %>
<%= f.time_select :duration, {}, { class: 'form-control time-select' }%>
In the controller
def create
#task = Task.new(task_params)
#hours = (params[:task]['duration(4i)']).to_i
#minutes = (params[:task]['duration(5i)']).to_i
#task.duration = #hours*60 + #minutes
respond_to do |format|
if #task.save
format.html { redirect_to #task, notice: 'Task was successfully created.' }
format.json { render :show, status: :created, location: #task }
else
format.html { render :new }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
def edit
#task = Task.find(params[:id])
#task['duration(4i)'] = (#task.duration / 60).to_s
#task['duration(5i)'] = (#task.duration % 60).to_s
end
It works for the create, but not for the edit. I am getting
can't write unknown attribute duration(4i)

Issue with has_and_belongs_to_many association in rails

Can you help a noob, please?
I have 2 models - Player and Poker Tables, which have has_and_belongs_to_many association. When i try create player i catch error
undefined method `poker_table'
respond_to do |format|
**if #player.save**
format.html { redirect_to #player, notice: 'Player was successfully created.' }
format.json { render :show, status: :created, location: #player }
else
I use checkboxes for mark needed poker tables, here form code:
<% #poker_tables = PokerTable.all %>
<% #poker_tables.each do |poker_table| %>
<div>
<%= check_box_tag "player[poker_table_ids][]", poker_table.id %>
<%= poker_table.name %>
<%= poker_table.actual_time %>
</div>
<% end %>
create method and params
def create
#player = Player.new(player_params)
respond_to do |format|
if #player.save
format.html { redirect_to #player, notice: 'Player was successfully created.' }
format.json { render :show, status: :created, location: #player }
else
format.html { render :new }
format.json { render json: #player.errors, status: :unprocessable_entity }
end
end
end
def player_params
params.require(:player).permit(:email, :poker_table_ids => [])
end
I can create poker table, but couldn't create a player with associated poker tables.
I don't really understand what I'm doing wrong. I studied a lot of resources about this theme, but i can't find answer.

Rails: how to create an Object with another object as its attribute simultaneously

I have a Customer object, which is just a holder for the People and Properties objects that will hold.
My problem seems to be that I want to make the Customer object and a Person object at the same time.
When I try to render the form to create the customer, there is a section for a form to create the Person. The Person needs the Customer's id, but apparently, that hasn't been created yet.
How can I make two objects simultaneously, one being the attribute of the first?
This is from my Customer controller:
def create
#customer = Customer.new(customer_params)
respond_to do |format|
if #customer.save
#customer.update(params.require(:customer).permit(:customer_person, person_atributes: [:id, :firstname, :lastname] ))
format.html { redirect_to #customer, notice: 'Customer was successfully created.' }
format.json { render :show, status: :created, location: #customer }
else
format.html { render :new }
format.json { render json: #customer.errors, status: :unprocessable_entity }
end
end
end
This is from the Customer form:
<snip>
<%= form_for([#customer,#customer.people.new]) do |f| %>
<div class="field">
<%f.label :firstname %><br />
<%f.text_field :firstname %>
</div>
</snip>

Rails collection_select field is repeating entries

In my rails app form, I've the following code for a multi-select:
<div class="field">
<%= f.label :frameworks %><br />
<%= f.collection_select :framework_ids, Framework.all, :id, :name, {}, {:multiple => true} %>
</div>
It works fine at creation, and it shows correctly the previowsly selected frameworks on edit view.
But when I submit some other updated fields, it repeats the frameworks entries in my database.
For example, if I had selected "framework1", "frameworks2", after updating I've in database "framework1", "frameworks2", "framework1", "frameworks2", and if I update one more time: "framework1", "frameworks2","framework1", "frameworks2","framework1", "frameworks2".
So what should I do to prevent it?
EDIT:
The controller is here:
#component = Component.find(params[:id])
respond_to do |format|
if #component.update_attributes(params[:component])
#component.update_attribute(:numImages, #component.assets.size)
#component.save
format.html { redirect_to #component, notice: 'Component was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #component.errors, status: :unprocessable_entity }
end
end
end
By the way, is correct to update :numImages as I do?
For the numImages update (your sub-question), I'd suggest using a before_update method in your Component model.
before_update :set_numimages
def set_numimages
numImages = assets.size
end
Also, you're calling update_attributes, update_attribute and save on #component. That invokes three save actions. I'd suggest you change it to this and see if the problem persists:
#component = Component.find(params[:id])
respond_to do |format|
if #component.update_attributes(params[:component])
format.html { redirect_to #component, notice: 'Component was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #component.errors, status: :unprocessable_entity }
end
end

Resources