1

I have an attribute called "features" in my application. In my form, "features" consists of a list of check boxes. The idea here is that users can check off which "features" apply to their post, and that list of features gets saved into the record.

I see the array being saved in my console ("features"=>{"Private bathroom"=>"1", "Elevator"=>"0", "Complimentary breakfast"=>"1", "Great view"=>"1", "Cable TV"=>"0", "Fireplace"=>"0", "Other (see description)"=>"0", "Sweet location"=>"0"}).

However... When I view the record, features returns nil. It doesn't seem to be saving the features array.

Code provided below. Any idea what I'm doing wrong here?

models/accommodation.rb

class Accommodation < ActiveRecord::Base
  validates_presence_of :title, :description, :thing, :location
  attr_accessible :photo_attributes, :title, :description, :thing, :borough, :location, :spaces, :price, :features
  has_one :photo
  has_many :requests
  belongs_to :user
  accepts_nested_attributes_for :photo, :allow_destroy => true
end

controllers/accommodation_controller.rb

class AccommodationsController < ApplicationController

  before_filter :auth, :except => :show

  uses_tiny_mce ( :options => {
    :theme => 'advanced',
    :theme_advanced_toolbar_location => 'top',
    :theme_advanced_toolbar_align => 'left',
    :theme_advanced_buttons1 => 'bold,italic,underline,image,bullist,numlist,separator,undo,redo',
    :theme_advanced_buttons2 => '',
    :theme_advanced_buttons3 => ''
  })

  def show
    @accommodation = Accommodation.find(params[:id])
  end

  def new
    @accommodation = current_user.accommodations.build
    @accommodation.build_photo
  end

  def create
    @accommodation = current_user.accommodations.build(params[:accommodation])
    if @accommodation.save
      flash[:notice] = "Successfully created your accommodation."
      redirect_to @accommodation
    else
      render :new
    end
  end

  def edit
    @accommodation = Accommodation.find(params[:id])
  end

  def update
    @accommodation = Accommodation.find(params[:id])
    if @accommodation.update_attributes(params[:accommodation])
      flash[:notice] = "Successfully updated accommodation."
      redirect_to @accommodation
    else
      render :edit
    end
  end

  def destroy
    @accommodation = Accommodation.find(params[:id])
    @accommodation.destroy
    flash[:notice] = "Successfully destroyed accommodation."
    redirect_to :inkeep
  end

  private

  def auth
    if current_user
      if params[:action] != 'new' && params[:action] != 'create'
        @accommodation = Accommodation.find(params[:id])
        if @accommodation.user_id != current_user.id
          flash[:notice] = "You don't own this accommodation!"
          render :action => 'show'
        end
      end
      return true
    else
      flash[:error]  = "Please login first."
      redirect_to :controller => 'sessions', :action => 'new'
    end
  end

end

views/accommodations/_form.html.erb

<%= form_for @accommodation, :html => {:multipart => true} do |f| %>
  <%= f.error_messages %>
  <p>
    Title<br />
    <%= f.text_field :title, :size => 60 %>
  </p>
  <p>
    Description<br />
    <%= f.text_area :description, :rows => 17, :cols => 75, :class => "mceEditor" %>
  </p>
  [...snip...]
  <p>
    <i>Featuring...</i>
    <%= fields_for :features do |feature_fields| %>
    <table>
        <tr>
            <td><%= feature_fields.check_box 'Private bathroom' %> Private bathroom</td>
            <td><%= feature_fields.check_box 'Cable TV' %> Cable TV</td>
            <td><%= feature_fields.check_box 'Complimentary breakfast' %> Complimentary breakfast</td>
        </tr>
        <tr>

            <td><%= feature_fields.check_box 'Elevator' %> Elevator</td>
            <td><%= feature_fields.check_box 'Fireplace' %> Fireplace</td>
            <td><%= feature_fields.check_box 'Great view' %> Great view</td>
        </tr>
        <tr>
            <td><%= feature_fields.check_box 'Sweet location' %> Sweet location</td>
            <td><%= feature_fields.check_box 'Other (see description)' %> Other (see description)</td>
        </tr>
    </table>
    <% end %>
  </p>
  [...snip...]
<% end %>
3
  • May need to have a look at the create action of your controller. Commented Dec 22, 2010 at 8:11
  • Can we see your model code? What's the database table(s) structure? Commented Dec 22, 2010 at 8:15
  • I've just added everything :) Commented Dec 22, 2010 at 8:23

3 Answers 3

3

First, is the features array inside of your the accommodation hash in the params hash?

Second, there is no db column type which accepts an array, so you need to put

serialize :features

in the model. This will store the array as yaml in the db. You can also specify the data type as an argument to serialize() (probably Array in this case), but it's not always necessary.

Sign up to request clarification or add additional context in comments.

4 Comments

I tried serializing :features, but it still isn't getting stored. It didn't seem to change anything, I still see: "features"=>{"Private bathroom"=>"1", "Elevator"=>"0", "Complimentary breakfast"=>"1", "Great view"=>"1", "Cable TV"=>"0", "Fireplace"=>"0", "Other (see description)"=>"0", "Sweet location"=>"0"}
My first step is usually to make sure the model is working in the console. If you do a = Accommodation.new a.features = {"Private bathroom"=>"1", "Elevator"=>"0", "Complimentary breakfast"=>"1", "Great view"=>"1", "Cable TV"=>"0", "Fireplace"=>"0", "Other (see description)"=>"0", "Sweet location"=>"0"} a.features #=> should return hash above a.save a.features #=> again, should return the hash This will at least tell you where the problem is
Can you post the entire params hash? Also, if you specified Array in the call to serialize, that would be incorrect without converting the hash passed to an array. Without that, it should be specified as a Hash.
Thank you, I will try both of these recommendations.
1

I add the same problem today, it appears the form isn't properly built in the view. Indeed, take a closer look at your params: params[:features] is outside params[:accomodation]

I simply added at the beginning of my create action:

 params[:accomodation][:features] = params[:features]

And it works properly

1 Comment

I think this may be because you are not calling fields_for on the f object. In other words, call f.fields_for :features...
0

What about your model? Do you have attr_accessible or attr_protected calls in there?

1 Comment

I just updated my post to show my model's code. The attribute is accessible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.