Ruby on rails 我在哪里使用find_或create_by方法?

Ruby on rails 我在哪里使用find_或create_by方法?,ruby-on-rails,Ruby On Rails,使用Rails方法时,find_或create_by,它属于模型还是控制器?我很难理解如何实际实现这个方法 我希望我的rails应用程序接受来自用户的JSON消息。用户将向服务器发送数据,以便将其保存在数据库中。也就是说,我假设用户必须使用“POST”或“PATCH”方法在我的服务器上存储或更新数据。当我查看路由时,创建操作使用“POST”方法 我已经阅读了以下Rails文档,但它没有向我澄清任何事情 我会像这样将find_或create_by方法放在我的create操作中吗?还是它属于其他地方

使用Rails方法时,find_或create_by,它属于模型还是控制器?我很难理解如何实际实现这个方法

我希望我的rails应用程序接受来自用户的JSON消息。用户将向服务器发送数据,以便将其保存在数据库中。也就是说,我假设用户必须使用“POST”或“PATCH”方法在我的服务器上存储或更新数据。当我查看路由时,创建操作使用“POST”方法

我已经阅读了以下Rails文档,但它没有向我澄清任何事情

我会像这样将find_或create_by方法放在我的create操作中吗?还是它属于其他地方?在创建操作中似乎不正确

class WifiNetworksController < ApplicationController
  def create
    @wifi_network = WifiNetwork.find_or_create_by(bssid: params[:bssid],
                                        ssid: params[:ssid],
                                        channel: params[:channel], etc...)
  end
end
class-WifiNetworksController
最终我想要:

  • 如果JSON不存在,用户可以通过JSON保存新网络
  • 如果某些属性有所改善(如信号强度),用户可以通过JSON更新现有网络
  • 谢谢你抽出时间

    最后更新-谢谢大家的建议!我不得不听取大家的一些建议才能使它发挥作用!下面是我最后做的。。似乎工作正常,没有错误

    def create
      respond_to do |format|
        if @wifi_network = WifiNetwork.find_by(bssid: wifi_network_params[:bssid])
          # Logic for checking whether to update the record or not
          @wifi_network.update_attributes(wifi_network_params) if @wifi_network.rssi < params[:rssi]
          format.json { render :nothing => true }
        else
          # Must be a new wifi network, create it
          @wifi_network = WifiNetwork.create(wifi_network_params)
          format.json { render :nothing => true }
        end
      end
    end
    
    def创建
    回应待办事项|格式|
    如果@wifi\u network=WifiNetwork.find\u by(bssid:wifi\u network\u参数[:bssid])
    #用于检查是否更新记录的逻辑
    @wifi_网络。如果@wifi_网络.rssitrue}
    其他的
    #必须是一个新的wifi网络,创建它
    @wifi_网络=WifiNetwork.create(wifi_网络参数)
    format.json{render:nothing=>true}
    结束
    结束
    结束
    
    如果使用强参数,则可以在控制器中执行此操作:

    def create
      @wifi_network = WifiNetwork.find_or_create_by(bssid: wifi_network_params[:bssid])
      @wifi_network.update_attributes(wifi_network_params)
    end
    
    然后,当用户进行卷曲时,如:

     curl -X POST localhost:3000/wifi_networks -d "wifi_network[bssid]=bssid1&wifi_network[ssid]=ssid1&wifi_network[channel]=channel1"
    

    您的创建操作将通过其bssid查找WifiNetwork并更新ssid和通道属性,或者如果它不存在,则将使用bssid参数创建WifiNetwork,然后使用其余ATT更新新创建的记录。要小心,因为如果其他属性的wifi\u network\u参数为空,它们会将参数更新为nil。

    我认为最好退一步,真正考虑一下应用程序的接口。您需要使用
    find\u或\u create\u by
    并在一个控制器操作中完成所有操作,这有什么特别的原因吗

    为什么不在您的
    WifiNetworksController
    上分别执行“创建”和“更新”操作,从而简化事情并遵守REST:

    class WifiNetworksController < ApplicationController
      def create
        @wifi_network = WifiNetwork.new(wifi_network_params)
    
        if @wifi_network.save
          # success response
        else
          # failure response
        end
      end
    
     def update
       # params[:id] won't work here if the client sending the request doesn't know the id of the
       # wifi network, so replace it with the attribute you expect to be able to 
       # uniquely identify a WifiNetwork with.
       if @wifi_network = WifiNetwork.find(params[:id])
         # Logic for deciding whether to update or not
         @wifi_network.update_attributes(wifi_network_params) if @wifi_network.signal_strength < params[:signal_strength]
       else
         # wifi_network not found, respond accordingly
       end
     end
    
     private
    
     # strong_parameters for Rails 4
     def wifi_network_params
       params.require(:wifi_network).permit(:ssid, :channel,...)
     end
    end
    

    您可以使用wifi\u network=WifiNetwork。通过(参数)查找或创建\u
    @Iceman谢谢您的建议。如果“bssid”是唯一值,则在使用强参数时会自动选择该值吗?谢谢您的帮助!我使用find_或create方法,因为它将被自动化系统使用。我不确定你是否熟悉Wardriving,但基本上它将是一个树莓皮寻找免费WiFi和开放热点。我的设想是,它将向服务器发送一条JSON消息。raspberry pi并没有真正决定记录是否存在,它只是将数据盲目地发送到服务器。很好,我更新了我的答案,因为你提供了一些关于问题的背景信息,澄清了问题。罗伯特,谢谢你的帮助。我正在尝试您的解决方案,以查看它是否有效。我正在尝试您的解决方案,但它仅通过发送bssid。。奇怪的我会继续努力的你允许强参数散列中的其他属性吗?是的,修复了它。。。无法解决创建操作未正确响应json的最后一些问题。。。我收到一个ActionController::UnknownFormat错误。。。现在正在玩格式块
      def create
        if @wifi_network = WifiNetwork.find(params[:bssid])
          # Logic for checking whether to update the record or not
          @wifi_network.update_attributes(wifi_network_params) if @wifi_network.signal_strength < params[:signal_strength]
        else
          # Must be a new wifi network, create it
          @wifi_network = WifiNetwork.create(wifi_network_params)
        end
      end