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
Related
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.
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.
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>
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.
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?