简体   繁体   中英

Rails form submit for two different models

I'm working on a simple webapp in which you import a CSV and search through it using Sunspot. The only actions being used by the user are Index and Show. All of this is working fine, but the end goal is to be able to track exactly what is being searched and export it.

My datasheets model is the one for the CSV being uploaded. Again this including the search is working fine. Both datasheets and datalog are scaffolded and routed by default.The first attempt at this I figured I would just add a definition in my DatasheetsController that will create a new instance of the datalog model using the search.

datasheets_controller.rb (working fine)

def index
  @search = Datasheet.search do
    fulltext params[:search]
  end

  @datasheets = @search.results

  respond_to do |format|
    ...
  end
end

Here's my attempt at creating a new datalog. I'm new at Rails and realize this isn't RESTful, but I'm ok with a quick and dirty solution here.

class DatasheetsController < ApplicationController

  after_filter :log_it

  def log_it
    @datalog = Datalog.new(params[:datalog])
  end

end

This didn't do anything with nothing helpful in development.log, so I tried changing the params to @datalog = Datalog.new(params[:search]) but it gave me a the following error:

NoMethodError in DatasheetsController#index

undefined method `stringify_keys` for "[whatever is searched for]":string

I'm sure I'm way off here but I figured this would be an easy thing to throw in, but it's not turning out to be. If it helps, once this works I'd like to make the datalog attribute :name created to be the same as the string that was searched for. Any point in the right direction (or smack for doing it so poorly) would be very much appreciated.

EDIT: I'd also like to add that if there is a simple way to log search results (it doesn't have to be in a model), anything is welcome (including gems). I've searched as many keyword variations as I could think of on Google and SO and haven't been able to find anything.

EDIT 2:

After editing a few things I've gotten closer, but I'm still having issues.

I've added the following to def index :

@logkey = :search

and changed the log_it definition to:

def log_it
  @datalog = Datalog.new(params[:id])
  @datalog.update_attribute(:name, @logkey)
end

Now a new Datalog will save on search which is great, but the :name attribute always ends up being "search".

An example table that I have right now for datalogs is:


Name

search Show Edit Destroy

search Show Edit Destroy

search Show Edit Destroy

search Show Edit Destroy

search Show Edit Destroy

New Datalog


I've tried changing the @logkey line to: @logkey = :search.to_s but it doesn't really effect anything.

EDIT in response to answer

SQL (0.5ms) INSERT INTO "datalogs" ("created_at", "name", "updated_at") VALUES (?, ?, ?, ?) [["created_at", Tue, 26 Feb 2013 18:26:04 UTC +00:00], ["name", nil], ["updated_at", Tue, 26 Feb 2013 18:26:04 UTC +00:00]]

Again if this is just a problem elsewhere I get that and I can look for it on my own time. Thanks again!

The issue is the following:

  • I am assuming that your Datalog model is derived from ActiveRecord::Base (standard way of doing models in rails)
  • .new method of this class ( documented here ) takes an attribute hash (and options, but we don't care about that right now )
    • from this hash .new tries to create an instance of the class using every key-value pair of the hash in a way that the instances key-named attribute should be set as the value
  • the problem is that params[:search] in your example can not be used as an argument for .new , so it throws an exception

How it should look like:

  • in the Datalog model you should have something like: :attr_accessor name
  • params should params[:search] = { :name => 'My favourite search name' }

Another notes
If you're running simply bundle exec rails s you can see your params in the server log. In production just use: less log/development.log . You can check what are you sending trough for your application.

Update after question update

@logkey = params[:search].to_s

Update after comment

Ok this @datalog.update_attribute(:name, @logkey) line is not necessary. Just go w/ your original one: @datalog = Datalog.new(params[:datalog]) it is the "rails way".

Keep in mind my first part of the answer, so params[:datalog] should be a hash. However if you can't manage to do that then just use:

@datalog = Datalog.new(params[:id])
@datalog.name = params[:search] # I dont think to_s is needed
@datalog.save # To save it into the database

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM